diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 8dc586ce114..c50e9d08e25 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,6 @@
**What type of PR is this?**
Fixes #
+
+
+Release Notes: Yes/No
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index c7a5bee84ff..8e8d33c94f1 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -6,64 +6,52 @@
version: 2
updates:
- package-ecosystem: docker
- directory: /tools/docker/envoy-gateway/
- schedule:
- interval: weekly
- - package-ecosystem: docker
- directory: /site
+ directories:
+ - /tools/docker/envoy-gateway/
+ - /site
schedule:
interval: weekly
- package-ecosystem: github-actions
- directory: /
+ directories:
+ - /
+ - /tools/github-actions/setup-deps
schedule:
interval: weekly
ignore:
# skip to update retest, because it won't work with the latest version
- dependency-name: "envoyproxy/toolshed/gh-actions/retest"
- - package-ecosystem: github-actions
- directory: /tools/github-actions/setup-deps
- schedule:
- interval: weekly
- package-ecosystem: gomod
- directory: /
+ directories:
+ - "/"
+ - "examples/extension-server"
schedule:
interval: weekly
groups:
k8s.io:
patterns:
- "k8s.io/*"
+ - "sigs.k8s.io/*"
go.opentelemetry.io:
patterns:
- "go.opentelemetry.io/*"
+ golang.org:
+ patterns:
+ - "golang.org/*"
+ - "google.golang.org/*"
+ - "google.golang.org/genproto/googleapis/*"
- package-ecosystem: pip
- directory: /tools/src/codespell
- schedule:
- interval: weekly
- - package-ecosystem: gomod
- directory: /tools/src/helm-docs
- schedule:
- interval: weekly
- - package-ecosystem: gomod
- directory: /tools/src/buf
+ directories:
+ - /tools/src/codespell
+ - /tools/src/sphinx-build
+ - /tools/src/yamllint
schedule:
interval: weekly
- package-ecosystem: gomod
- directory: /tools/src/golangci-lint
- schedule:
- interval: weekly
- - package-ecosystem: gomod
- directory: /tools/src/kind
- schedule:
- interval: weekly
- - package-ecosystem: gomod
- directory: /tools/src/setup-envtest
- schedule:
- interval: weekly
- - package-ecosystem: pip
- directory: /tools/src/sphinx-build
- schedule:
- interval: weekly
- - package-ecosystem: pip
- directory: /tools/src/yamllint
+ directories:
+ - /tools/src/helm-docs
+ - /tools/src/buf
+ - /tools/src/golangci-lint
+ - /tools/src/kind
+ - /tools/src/setup-envtest
schedule:
interval: weekly
diff --git a/.github/markdown_lint_config.json b/.github/markdown_lint_config.json
index 85aaabec0e9..8c62b98bfd3 100644
--- a/.github/markdown_lint_config.json
+++ b/.github/markdown_lint_config.json
@@ -49,5 +49,7 @@
"MD048": false,
"MD049": false,
"MD050": false,
- "MD051": false
+ "MD051": false,
+ "MD055": false,
+ "MD056": false
}
diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml
index 0a367a06d65..81a08eb76b3 100644
--- a/.github/workflows/build_and_test.yaml
+++ b/.github/workflows/build_and_test.yaml
@@ -20,7 +20,7 @@ jobs:
lint:
runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
# Generate the installation manifests first, so it can check
# for errors while running `make -k lint`
@@ -31,14 +31,14 @@ jobs:
gen-check:
runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
- run: make -k gen-check
license-check:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
- run: make -k licensecheck
@@ -48,33 +48,33 @@ jobs:
contents: read # for actions/checkout
id-token: write # for fetching OIDC token
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
# test
- name: Run Coverage Tests
run: make go.test.coverage
- name: Upload coverage to Codecov
- uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
+ uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
with:
fail_ci_if_error: true
files: ./coverage.xml
name: codecov-envoy-gateway
verbose: true
- use_oidc: true
+ use_oidc: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork) }}
build:
runs-on: ubuntu-latest
needs: [lint, gen-check, license-check, coverage-test]
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
- name: Build EG Multiarch Binaries
run: make build-multiarch PLATFORMS="linux_amd64 linux_arm64"
- name: Upload EG Binaries
- uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
+ uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: envoy-gateway
path: bin/
@@ -83,10 +83,11 @@ jobs:
runs-on: ubuntu-latest
needs: [build]
strategy:
+ fail-fast: false
matrix:
- version: [ v1.27.13, v1.28.9, v1.29.4, v1.30.0 ]
+ version: [ v1.29.10, v1.30.6, v1.31.4, v1.32.0 ]
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
- name: Download EG Binaries
@@ -111,10 +112,20 @@ jobs:
runs-on: ubuntu-latest
needs: [build]
strategy:
+ fail-fast: false
matrix:
- version: [ v1.27.13, v1.28.9, v1.29.4, v1.30.0 ]
+ target:
+ - version: v1.29.10
+ ipFamily: ipv4
+ - version: v1.30.6
+ ipFamily: ipv4
+ - version: v1.31.4
+ ipFamily: ipv6 # only run ipv6 test on this version to save time
+ # TODO: this's IPv4 first, need a way to test IPv6 first.
+ - version: v1.32.0
+ ipFamily: dual # only run dual test on latest version to save time
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
- name: Download EG Binaries
@@ -131,8 +142,10 @@ jobs:
# E2E
- name: Run E2E Tests
env:
- KIND_NODE_TAG: ${{ matrix.version }}
+ KIND_NODE_TAG: ${{ matrix.target.version }}
IMAGE_PULL_POLICY: IfNotPresent
+ IP_FAMILY: ${{ matrix.target.ipFamily }}
+ E2E_TIMEOUT: 1h
run: make e2e
benchmark-test:
@@ -141,13 +154,16 @@ jobs:
if: ${{ ! startsWith(github.event_name, 'push') }}
needs: [build]
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
+ - name: Setup Graphviz
+ uses: ts-graphviz/setup-graphviz@b1de5da23ed0a6d14e0aeee8ed52fdd87af2363c # v2.0.2
+
# Benchmark
- name: Run Benchmark tests
env:
- KIND_NODE_TAG: v1.28.9
+ KIND_NODE_TAG: v1.29.10
IMAGE_PULL_POLICY: IfNotPresent
# Args for benchmark test
BENCHMARK_RPS: 10000
@@ -160,12 +176,25 @@ jobs:
- name: Read Benchmark report
run: cat test/benchmark/benchmark_report/benchmark_report.md
+ resilience-test:
+ runs-on: ubuntu-latest
+ if: ${{ ! startsWith(github.event_name, 'push') }}
+ needs: [build]
+ steps:
+ - uses: actions/checkout@v4.2.2
+ - uses: ./tools/github-actions/setup-deps
+ - name: Resilience Test
+ env:
+ KIND_NODE_TAG: v1.28.13
+ IMAGE_PULL_POLICY: IfNotPresent
+ CUSTOM_CNI: "true"
+ run: make resilience
publish:
runs-on: ubuntu-latest
needs: [conformance-test, e2e-test]
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
- name: Download EG Binaries
@@ -182,7 +211,7 @@ jobs:
# build and push image
- name: Login to DockerHub
if: github.event_name == 'push'
- uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
+ uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
@@ -205,4 +234,6 @@ jobs:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
# use `0.0.0` as the default latest version.
# use `Always` image pull policy for latest version.
- run: IMAGE_PULL_POLICY=Always OCI_REGISTRY=oci://docker.io/envoyproxy CHART_VERSION=v0.0.0-latest TAG=latest make helm-push
+ run: |
+ IMAGE_PULL_POLICY=Always OCI_REGISTRY=oci://docker.io/envoyproxy CHART_VERSION=v0.0.0-latest TAG=latest make helm-push
+ IMAGE_PULL_POLICY=Always OCI_REGISTRY=oci://docker.io/envoyproxy CHART_VERSION=0.0.0-latest TAG=latest make helm-push
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 82d7ab684a7..a0f9fd211f1 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -32,18 +32,18 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
- name: Initialize CodeQL
- uses: github/codeql-action/init@2d790406f505036ef40ecba973cc774a50395aac # v3.25.13
+ uses: github/codeql-action/init@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9
with:
languages: ${{ matrix.language }}
- name: Autobuild
- uses: github/codeql-action/autobuild@2d790406f505036ef40ecba973cc774a50395aac # v3.25.13
+ uses: github/codeql-action/autobuild@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@2d790406f505036ef40ecba973cc774a50395aac # v3.25.13
+ uses: github/codeql-action/analyze@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9
with:
category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml
index 0b4cb36ecf6..b147f5e5cf0 100644
--- a/.github/workflows/docs.yaml
+++ b/.github/workflows/docs.yaml
@@ -3,14 +3,12 @@ on:
push:
branches:
- "main"
- - "release/v*"
paths:
- 'site/**'
- 'tools/make/docs.mk'
pull_request:
branches:
- "main"
- - "release/v*"
paths:
- 'site/**'
- 'tools/make/docs.mk'
@@ -23,7 +21,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out code
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
@@ -48,7 +46,7 @@ jobs:
contents: write
steps:
- name: Git checkout
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
ref: ${{ github.event.pull_request.head.sha }}
@@ -62,7 +60,7 @@ jobs:
extended: true
- name: Setup Node
- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.1.0
+ uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '18'
diff --git a/.github/workflows/experimental_conformance.yaml b/.github/workflows/experimental_conformance.yaml
index 4c2d2e60f06..f2de92a63b7 100644
--- a/.github/workflows/experimental_conformance.yaml
+++ b/.github/workflows/experimental_conformance.yaml
@@ -3,10 +3,11 @@ on:
push:
paths:
- 'charts/gateway-helm/crds/gatewayapi-crds.yaml'
+ - 'test/conformance/experimental_conformance_test.go'
pull_request:
paths:
- 'charts/gateway-helm/crds/gatewayapi-crds.yaml'
- - 'test/conformance/*.go'
+ - 'test/conformance/experimental_conformance_test.go'
# Add workflow_dispatch to trigger this workflow manually by maintainers.
workflow_dispatch:
@@ -18,9 +19,9 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- version: [ v1.27.13, v1.28.9, v1.29.4, v1.30.0 ]
+ version: [ v1.29.10, v1.30.6, v1.31.4, v1.32.0 ]
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
# gateway api experimental conformance
@@ -32,7 +33,7 @@ jobs:
run: make experimental-conformance
- name: Upload Conformance Report
- uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
+ uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: conformance-report-k8s-${{ matrix.version }}
path: ./test/conformance/conformance-report-k8s-${{ matrix.version }}.yaml
diff --git a/.github/workflows/latest_release.yaml b/.github/workflows/latest_release.yaml
index c3f23909e37..e3ab700bd23 100644
--- a/.github/workflows/latest_release.yaml
+++ b/.github/workflows/latest_release.yaml
@@ -22,13 +22,16 @@ jobs:
benchmark-test:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
+ - name: Setup Graphviz
+ uses: ts-graphviz/setup-graphviz@b1de5da23ed0a6d14e0aeee8ed52fdd87af2363c # v2.0.2
+
# Benchmark
- name: Run Benchmark tests
env:
- KIND_NODE_TAG: v1.28.9
+ KIND_NODE_TAG: v1.29.10
IMAGE_PULL_POLICY: IfNotPresent
# Args for benchmark test
BENCHMARK_RPS: 10000
@@ -43,7 +46,7 @@ jobs:
run: cd test/benchmark && zip -r benchmark_report.zip benchmark_report
- name: Upload Benchmark Report
- uses: actions/upload-artifact@v4 # version is better be consistent with actions/download-artifact
+ uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: benchmark_report
path: test/benchmark/benchmark_report.zip
@@ -54,7 +57,7 @@ jobs:
permissions:
contents: write
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
- name: Generate Release Manifests
@@ -62,18 +65,22 @@ jobs:
run: IMAGE_PULL_POLICY=Always make generate-manifests IMAGE=envoyproxy/gateway-dev TAG=latest OUTPUT_DIR=release-artifacts
- name: Download Benchmark Report
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: benchmark_report
path: release-artifacts
- name: Build egctl latest multiarch binaries
run: |
- make build-multiarch BINS="egctl"
- tar -zcvf egctl_latest_linux_amd64.tar.gz bin/linux/amd64/
- tar -zcvf egctl_latest_linux_arm64.tar.gz bin/linux/arm64/
- tar -zcvf egctl_latest_darwin_amd64.tar.gz bin/darwin/amd64/
- tar -zcvf egctl_latest_darwin_arm64.tar.gz bin/darwin/arm64/
+ make build-multiarch
+ tar -zcvf envoy-gateway_latest_linux_amd64.tar.gz bin/linux/amd64/envoy-gateway
+ tar -zcvf envoy-gateway_latest_linux_arm64.tar.gz bin/linux/arm64/envoy-gateway
+ tar -zcvf envoy-gateway_latest_darwin_amd64.tar.gz bin/darwin/amd64/envoy-gateway
+ tar -zcvf envoy-gateway_latest_darwin_arm64.tar.gz bin/darwin/arm64/envoy-gateway
+ tar -zcvf egctl_latest_linux_amd64.tar.gz bin/linux/amd64/egctl
+ tar -zcvf egctl_latest_linux_arm64.tar.gz bin/linux/arm64/egctl
+ tar -zcvf egctl_latest_darwin_amd64.tar.gz bin/darwin/amd64/egctl
+ tar -zcvf egctl_latest_darwin_arm64.tar.gz bin/darwin/arm64/egctl
# Ignore the error when we delete the latest release, it might not exist.
@@ -100,7 +107,7 @@ jobs:
GITHUB_REPOSITORY: ${{ github.repository_owner }}/${{ github.event.repository.name }}
- name: Recreate the Latest Release and Tag
- uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v0.1.15
+ uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # v2.1.0
with:
draft: false
prerelease: true
@@ -109,6 +116,10 @@ jobs:
release-artifacts/install.yaml
release-artifacts/quickstart.yaml
release-artifacts/benchmark_report.zip
+ envoy-gateway_latest_linux_amd64.tar.gz
+ envoy-gateway_latest_linux_arm64.tar.gz
+ envoy-gateway_latest_darwin_amd64.tar.gz
+ envoy-gateway_latest_darwin_arm64.tar.gz
egctl_latest_linux_amd64.tar.gz
egctl_latest_linux_arm64.tar.gz
egctl_latest_darwin_amd64.tar.gz
diff --git a/.github/workflows/license-scan.yml b/.github/workflows/license-scan.yml
index 31014adf8a5..c6dea873862 100644
--- a/.github/workflows/license-scan.yml
+++ b/.github/workflows/license-scan.yml
@@ -16,12 +16,12 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run scanner
- uses: google/osv-scanner-action/osv-scanner-action@7ac94f9d40028db4cacf8d53adec6626f5d3d2f7 # v1.8.2
+ uses: google/osv-scanner-action/osv-scanner-action@19ec1116569a47416e11a45848722b1af31a857b # v1.9.0
with:
scan-args: |-
--skip-git
--experimental-licenses=Apache-2.0,BSD-2-Clause,BSD-2-Clause-FreeBSD,BSD-3-Clause,MIT,ISC,Python-2.0,PostgreSQL,X11,Zlib
+ --config tools/osv-scanner/license-scan-config.toml
./
- continue-on-error: true # TODO remove once all issues are resolved
diff --git a/.github/workflows/osv-scanner.yml b/.github/workflows/osv-scanner.yml
index 424ff41a189..bea1c1a15fd 100644
--- a/.github/workflows/osv-scanner.yml
+++ b/.github/workflows/osv-scanner.yml
@@ -13,34 +13,40 @@ on:
schedule:
- cron: '44 15 * * 5'
+permissions:
+ contents: read
+
jobs:
scan-scheduled:
if: ${{ github.event_name == 'push' || github.event_name == 'schedule' }}
- uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@7ac94f9d40028db4cacf8d53adec6626f5d3d2f7" # v1.8.2
+ runs-on: ubuntu-latest
+ steps:
+ - uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@19ec1116569a47416e11a45848722b1af31a857b" # v1.9.0
+ with:
+ scan-args: |-
+ --skip-git
+ --recursive
+ ./
permissions:
actions: read
contents: read
# Require writing security events to upload SARIF file to security tab
security-events: write
- with:
- scan-args: |-
- --skip-git
- --recursive
- ./
- --config
- tools/osv-scanner/config.toml
scan-pr:
if: ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }}
- uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@7ac94f9d40028db4cacf8d53adec6626f5d3d2f7" # v1.8.2
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/setup-go@v5
+ with:
+ go-version: '1.23.4'
+ - uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@19ec1116569a47416e11a45848722b1af31a857b" # v1.9.0
+ with:
+ scan-args: |-
+ --skip-git
+ --recursive
+ ./
permissions:
actions: read
contents: read
security-events: write
- with:
- scan-args: |-
- --skip-git
- --recursive
- ./
- --config
- tools/osv-scanner/config.toml
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 3fc2409a90f..f513ab898f7 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -15,13 +15,16 @@ jobs:
benchmark-test:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./tools/github-actions/setup-deps
+ - name: Setup Graphviz
+ uses: ts-graphviz/setup-graphviz@b1de5da23ed0a6d14e0aeee8ed52fdd87af2363c # v2.0.2
+
# Benchmark
- name: Run Benchmark tests
env:
- KIND_NODE_TAG: v1.28.9
+ KIND_NODE_TAG: v1.29.10
IMAGE_PULL_POLICY: IfNotPresent
# Args for benchmark test
BENCHMARK_RPS: 10000
@@ -36,7 +39,7 @@ jobs:
run: cd test/benchmark && zip -r benchmark_report.zip benchmark_report
- name: Upload Benchmark Report
- uses: actions/upload-artifact@v4 # version is better be consistent with actions/download-artifact
+ uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: benchmark_report
path: test/benchmark/benchmark_report.zip
@@ -47,17 +50,18 @@ jobs:
permissions:
contents: write
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Extract Release Tag and Commit SHA
id: vars
shell: bash
run: |
echo "release_tag=$(echo ${GITHUB_REF##*/})" >> $GITHUB_ENV
+ echo "without_v_release_tag=$(echo ${GITHUB_REF##*/v})" >> $GITHUB_ENV
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Login to DockerHub
- uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
+ uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
@@ -69,23 +73,41 @@ jobs:
run: IMAGE_PULL_POLICY=IfNotPresent make generate-artifacts IMAGE=envoyproxy/gateway TAG=${{ env.release_tag }} OUTPUT_DIR=release-artifacts
- name: Build and Push EG Release Helm Chart
- run: IMAGE_PULL_POLICY=IfNotPresent OCI_REGISTRY=oci://docker.io/envoyproxy CHART_VERSION=${{ env.release_tag }} IMAGE=docker.io/envoyproxy/gateway TAG=${{ env.release_tag }} make helm-package helm-push
+ run: |
+ IMAGE_PULL_POLICY=IfNotPresent OCI_REGISTRY=oci://docker.io/envoyproxy CHART_VERSION=${{ env.release_tag }} IMAGE=docker.io/envoyproxy/gateway TAG=${{ env.release_tag }} make helm-package helm-push
+ IMAGE_PULL_POLICY=IfNotPresent OCI_REGISTRY=oci://docker.io/envoyproxy CHART_VERSION=${{ env.without_v_release_tag }} IMAGE=docker.io/envoyproxy/gateway TAG=${{ env.release_tag }} make helm-package helm-push
- name: Download Benchmark Report
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: benchmark_report
path: release-artifacts
+ - name: Build egctl multiarch binaries
+ run: |
+ make build-multiarch
+ tar -zcvf envoy-gateway_${{ env.release_tag }}_linux_amd64.tar.gz bin/linux/amd64/envoy-gateway
+ tar -zcvf envoy-gateway_${{ env.release_tag }}_linux_arm64.tar.gz bin/linux/arm64/envoy-gateway
+ tar -zcvf envoy-gateway_${{ env.release_tag }}_darwin_amd64.tar.gz bin/darwin/amd64/envoy-gateway
+ tar -zcvf envoy-gateway_${{ env.release_tag }}_darwin_arm64.tar.gz bin/darwin/arm64/envoy-gateway
+ tar -zcvf egctl_${{ env.release_tag }}_linux_amd64.tar.gz bin/linux/amd64/egctl
+ tar -zcvf egctl_${{ env.release_tag }}_linux_arm64.tar.gz bin/linux/arm64/egctl
+ tar -zcvf egctl_${{ env.release_tag }}_darwin_amd64.tar.gz bin/darwin/amd64/egctl
+ tar -zcvf egctl_${{ env.release_tag }}_darwin_arm64.tar.gz bin/darwin/arm64/egctl
+
- name: Upload Release Manifests
- uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v0.1.15
+ uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # v2.1.0
with:
files: |
release-artifacts/install.yaml
release-artifacts/quickstart.yaml
release-artifacts/release-notes.yaml
release-artifacts/benchmark_report.zip
- release-artifacts/egctl_${{ env.release_tag }}_linux_amd64.tar.gz
- release-artifacts/egctl_${{ env.release_tag }}_linux_arm64.tar.gz
- release-artifacts/egctl_${{ env.release_tag }}_darwin_amd64.tar.gz
- release-artifacts/egctl_${{ env.release_tag }}_darwin_arm64.tar.gz
+ envoy-gateway_${{ env.release_tag }}_linux_amd64.tar.gz
+ envoy-gateway_${{ env.release_tag }}_linux_arm64.tar.gz
+ envoy-gateway_${{ env.release_tag }}_darwin_amd64.tar.gz
+ envoy-gateway_${{ env.release_tag }}_darwin_arm64.tar.gz
+ egctl_${{ env.release_tag }}_linux_amd64.tar.gz
+ egctl_${{ env.release_tag }}_linux_arm64.tar.gz
+ egctl_${{ env.release_tag }}_darwin_amd64.tar.gz
+ egctl_${{ env.release_tag }}_darwin_arm64.tar.gz
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 91ba65f0069..8023a5d51c0 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -21,25 +21,25 @@ jobs:
steps:
- name: "Checkout code"
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: "Run analysis"
- uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
+ uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
with:
results_file: results.sarif
results_format: sarif
publish_results: true
- name: "Upload artifact"
- uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
+ uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: SARIF file
path: results.sarif
retention-days: 5
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@2d790406f505036ef40ecba973cc774a50395aac # v3.25.13
+ uses: github/codeql-action/upload-sarif@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9
with:
sarif_file: results.sarif
diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml
index 24570e7f064..bd3d3bde934 100644
--- a/.github/workflows/trivy.yml
+++ b/.github/workflows/trivy.yml
@@ -18,14 +18,14 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Build an image from Dockerfile
run: |
IMAGE=envoy-proxy/gateway-dev TAG=${{ github.sha }} make image
- name: Run Trivy vulnerability scanner
- uses: aquasecurity/trivy-action@6e7b7d1fd3e4fef0c5fa8cce1229c54b2c9bd0d8 # v0.24.0
+ uses: aquasecurity/trivy-action@18f2510ee396bbf400402947b394f2dd8c87dbb0 # v0.29.0
with:
image-ref: envoy-proxy/gateway-dev:${{ github.sha }}
exit-code: '1'
diff --git a/ADOPTERS.md b/ADOPTERS.md
deleted file mode 100644
index 5914f698e7b..00000000000
--- a/ADOPTERS.md
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-# Envoy Gateway Adopters
-
-This page contains a list of organizations who are users of Envoy Gateway, following the [definitions provided by the CNCF](https://github.com/cncf/toc/blob/main/FAQ.md#what-is-the-definition-of-an-adopter).
-
-If you would like to be included in this table, please submit a PR to this file or comment to [this issue](https://github.com/envoyproxy/gateway/issues/2781) and your information will be added.
-
-## AllFactors
-* Website https://allfactors.com
-* Category: End User
-* Environments:
-* Use Case:
- - Routing all customer traffic to our various backends. Every time a new customer signs up we dynamically add a
- route to a new hostname so Envoy Gateway is deeply integrated with our product.
-* Status: production
-* Logo: https://allfactors.com/AllFactors-Logo.svg
-
-## Tetrate
-* Website: https://www.tetrate.io
-* Category: Service Provider
-* Environments: AWS
-* Use Cases:
- - Tetrate provides Enterprise Gateway (TEG) to end users, which includes a 100% upstream distribution of Envoy Gateway, and management to deliver applications securely, authenticate user traffic, protect services with rate limiting and WAF, and integrate with your observability stack to monitor and observe activity.
-* Status: production
-* (Option) https://tetrate.io/wp-content/uploads/2023/03/tetrate-logo-dark.svg
-* (Option) Description:
-
-## Airspace Link
-* Organizatioin: Airspace Link
-* Website: https://airspacelink.com/
-* Category: End User
-* Environments: Azure
-* Use Cases:
- - Airspace Link is using Envoy Gateway to route all public APIs to Kubernetes clusters, developers are manipulating routes descriptions using agnostic manifest files, which are then automatically provisioned using Envoy Gateway.
-* Status: production
-* Logo: https://airhub.airspacelink.com/images/asl-flat-logo.png
diff --git a/OWNERS b/OWNERS
index 9237b007189..4a2e54e6db2 100644
--- a/OWNERS
+++ b/OWNERS
@@ -9,7 +9,6 @@ admins:
maintainers:
-- AliceProxy
- arkodg
- Xunzhuo
- zirain
@@ -25,6 +24,7 @@ emeritus-maintainers:
- skriss
- youngnick
- qicz
+- Alice-Lilith
reviewers:
diff --git a/README.md b/README.md
index 25fa9af8d94..2260a1fa72c 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,8 @@
[![OSV-Scanner](https://github.com/envoyproxy/gateway/actions/workflows/osv-scanner.yml/badge.svg)](https://github.com/envoyproxy/gateway/actions/workflows/osv-scanner.yml)
[![Trivy](https://github.com/envoyproxy/gateway/actions/workflows/trivy.yml/badge.svg)](https://github.com/envoyproxy/gateway/actions/workflows/trivy.yml)
+![Envoy Gateway Logo](https://github.com/cncf/artwork/blob/main/projects/envoy/envoy-gateway/horizontal/color/envoy-gateway-horizontal-color.svg)
+
Envoy Gateway is an open source project for managing Envoy Proxy as a standalone or
Kubernetes-based application gateway.
[Gateway API](https://gateway-api.sigs.k8s.io) resources are used to dynamically provision and configure the managed Envoy Proxies.
diff --git a/VERSION b/VERSION
index 795460fcec8..c7cd5b26796 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-v1.1.0
+v1.2.4
diff --git a/api/v1alpha1/accesslogging_types.go b/api/v1alpha1/accesslogging_types.go
index 24272564488..de34acdcd7d 100644
--- a/api/v1alpha1/accesslogging_types.go
+++ b/api/v1alpha1/accesslogging_types.go
@@ -24,14 +24,35 @@ type ProxyAccessLogSetting struct {
// Matches defines the match conditions for accesslog in CEL expression.
// An accesslog will be emitted only when one or more match conditions are evaluated to true.
// Invalid [CEL](https://www.envoyproxy.io/docs/envoy/latest/xds/type/v3/cel.proto.html#common-expression-language-cel-proto) expressions will be ignored.
- // +notImplementedHide
+ // +kubebuilder:validation:MaxItems=10
Matches []string `json:"matches,omitempty"`
// Sinks defines the sinks of accesslog.
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=50
Sinks []ProxyAccessLogSink `json:"sinks"`
+ // Type defines the component emitting the accesslog, such as Listener and Route.
+ // If type not defined, the setting would apply to:
+ // (1) All Routes.
+ // (2) Listeners if and only if Envoy does not find a matching route for a request.
+ // If type is defined, the accesslog settings would apply to the relevant component (as-is).
+ // +kubebuilder:validation:Enum=Listener;Route
+ // +optional
+ Type *ProxyAccessLogType `json:"type,omitempty"`
}
+type ProxyAccessLogType string
+
+const (
+ // ProxyAccessLogTypeListener defines the accesslog for Listeners.
+ // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-access-log
+ ProxyAccessLogTypeListener ProxyAccessLogType = "Listener"
+ // ProxyAccessLogTypeRoute defines the accesslog for HTTP, GRPC, UDP and TCP Routes.
+ // https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/udp/udp_proxy/v3/udp_proxy.proto#envoy-v3-api-field-extensions-filters-udp-udp-proxy-v3-udpproxyconfig-access-log
+ // https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto#envoy-v3-api-field-extensions-filters-network-tcp-proxy-v3-tcpproxy-access-log
+ // https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-access-log
+ ProxyAccessLogTypeRoute ProxyAccessLogType = "Route"
+)
+
type ProxyAccessLogFormatType string
const (
@@ -117,21 +138,16 @@ const (
// The service must implement the Envoy gRPC Access Log Service streaming API:
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/accesslog/v3/als.proto
// Access log format information is passed in the form of gRPC metadata when the
-// stream is established. Specifically, the following metadata is passed:
-//
-// - `x-accesslog-text` - The access log format string when a Text format is used.
-// - `x-accesslog-attr` - JSON encoded key/value pairs when a JSON format is used.
+// stream is established.
//
// +kubebuilder:validation:XValidation:rule="self.type == 'HTTP' || !has(self.http)",message="The http field may only be set when type is HTTP."
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="must have at least one backend in backendRefs",rule="has(self.backendRefs) && self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true"
type ALSEnvoyProxyAccessLog struct {
- // BackendRefs references a Kubernetes object that represents the gRPC service to which
- // the access logs will be sent. Currently only Service is supported.
- //
- // +kubebuilder:validation:MinItems=1
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs"`
+ BackendCluster `json:",inline"`
+
// LogName defines the friendly name of the access log to be returned in
// StreamAccessLogsMessage.Identifier. This allows the access log server
// to differentiate between different access logs coming from the same Envoy.
@@ -167,7 +183,11 @@ type FileEnvoyProxyAccessLog struct {
// OpenTelemetryEnvoyProxyAccessLog defines the OpenTelemetry access log sink.
//
// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true"
type OpenTelemetryEnvoyProxyAccessLog struct {
+ BackendCluster `json:",inline"`
// Host define the extension service hostname.
// Deprecated: Use BackendRefs instead.
//
@@ -180,15 +200,6 @@ type OpenTelemetryEnvoyProxyAccessLog struct {
// +kubebuilder:validation:Minimum=0
// +kubebuilder:default=4317
Port int32 `json:"port,omitempty"`
- // BackendRefs references a Kubernetes object that represents the
- // backend server to which the access log will be sent.
- // Only Service kind is supported for now.
- //
- // +optional
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs,omitempty"`
// Resources is a set of labels that describe the source of a log entry, including envoy node info.
// It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/).
// +optional
diff --git a/api/v1alpha1/authorization_types.go b/api/v1alpha1/authorization_types.go
index 3a589daef9f..5a99b4401a4 100644
--- a/api/v1alpha1/authorization_types.go
+++ b/api/v1alpha1/authorization_types.go
@@ -28,36 +28,132 @@ type Authorization struct {
// AuthorizationRule defines a single authorization rule.
type AuthorizationRule struct {
// Name is a user-friendly name for the rule.
- // If not specified, Envoy Gateway will generate a unique name for the rule.n
+ // If not specified, Envoy Gateway will generate a unique name for the rule.
+ //
// +optional
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=253
Name *string `json:"name,omitempty"`
// Action defines the action to be taken if the rule matches.
Action AuthorizationAction `json:"action"`
// Principal specifies the client identity of a request.
+ // If there are multiple principal types, all principals must match for the rule to match.
+ // For example, if there are two principals: one for client IP and one for JWT claim,
+ // the rule will match only if both the client IP and the JWT claim match.
Principal Principal `json:"principal"`
}
// Principal specifies the client identity of a request.
// A client identity can be a client IP, a JWT claim, username from the Authorization header,
// or any other identity that can be extracted from a custom header.
-// Currently, only the client IP is supported.
+
+// If there are multiple principal types, all principals must match for the rule to match.
+//
+// +kubebuilder:validation:XValidation:rule="(has(self.clientCIDRs) || has(self.jwt))",message="at least one of clientCIDRs or jwt must be specified"
type Principal struct {
// ClientCIDRs are the IP CIDR ranges of the client.
// Valid examples are "192.168.1.0/24" or "2001:db8::/64"
//
+ // If multiple CIDR ranges are specified, one of the CIDR ranges must match
+ // the client IP for the rule to match.
+ //
// The client IP is inferred from the X-Forwarded-For header, a custom header,
// or the proxy protocol.
// You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in
// the `ClientTrafficPolicy` to configure how the client IP is detected.
+ // +optional
// +kubebuilder:validation:MinItems=1
- ClientCIDRs []CIDR `json:"clientCIDRs"`
+ ClientCIDRs []CIDR `json:"clientCIDRs,omitempty"`
- // TODO: Zhaohuabing the MinItems=1 validation can be relaxed to allow empty list
- // after other principal types are supported. However, at least one principal is required
+ // JWT authorize the request based on the JWT claims and scopes.
+ // Note: in order to use JWT claims for authorization, you must configure the
+ // JWT authentication in the same `SecurityPolicy`.
+ // +optional
+ JWT *JWTPrincipal `json:"jwt,omitempty"`
}
+// JWTPrincipal specifies the client identity of a request based on the JWT claims and scopes.
+// At least one of the claims or scopes must be specified.
+// Claims and scopes are And-ed together if both are specified.
+//
+// +kubebuilder:validation:XValidation:rule="(has(self.claims) || has(self.scopes))",message="at least one of claims or scopes must be specified"
+type JWTPrincipal struct {
+ // Provider is the name of the JWT provider that used to verify the JWT token.
+ // In order to use JWT claims for authorization, you must configure the JWT
+ // authentication with the same provider in the same `SecurityPolicy`.
+ //
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=253
+ Provider string `json:"provider"`
+
+ // Claims are the claims in a JWT token.
+ //
+ // If multiple claims are specified, all claims must match for the rule to match.
+ // For example, if there are two claims: one for the audience and one for the issuer,
+ // the rule will match only if both the audience and the issuer match.
+ //
+ // +optional
+ // +kubebuilder:validation:MinItems=1
+ // +kubebuilder:validation:MaxItems=16
+ Claims []JWTClaim `json:"claims,omitempty"`
+
+ // Scopes are a special type of claim in a JWT token that represents the permissions of the client.
+ //
+ // The value of the scopes field should be a space delimited string that is expected in the scope parameter,
+ // as defined in RFC 6749: https://datatracker.ietf.org/doc/html/rfc6749#page-23.
+ //
+ // If multiple scopes are specified, all scopes must match for the rule to match.
+ //
+ // +optional
+ // +kubebuilder:validation:MinItems=1
+ // +kubebuilder:validation:MaxItems=16
+ Scopes []JWTScope `json:"scopes,omitempty"`
+}
+
+// JWTClaim specifies a claim in a JWT token.
+type JWTClaim struct {
+ // Name is the name of the claim.
+ // If it is a nested claim, use a dot (.) separated string as the name to
+ // represent the full path to the claim.
+ // For example, if the claim is in the "department" field in the "organization" field,
+ // the name should be "organization.department".
+ //
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=253
+ Name string `json:"name"`
+
+ // ValueType is the type of the claim value.
+ // Only String and StringArray types are supported for now.
+ //
+ // +kubebuilder:validation:Enum=String;StringArray
+ // +kubebuilder:default=String
+ // +unionDiscriminator
+ // +optional
+ ValueType *JWTClaimValueType `json:"valueType,omitempty"`
+
+ // Values are the values that the claim must match.
+ // If the claim is a string type, the specified value must match exactly.
+ // If the claim is a string array type, the specified value must match one of the values in the array.
+ // If multiple values are specified, one of the values must match for the rule to match.
+ //
+ // +kubebuilder:validation:MinItems=1
+ // +kubebuilder:validation:MaxItems=16
+ Values []string `json:"values"`
+}
+
+// +kubebuilder:validation:MinLength=1
+// +kubebuilder:validation:MaxLength=253
+type JWTScope string
+
+type JWTClaimValueType string
+
+const (
+ JWTClaimValueTypeString JWTClaimValueType = "String"
+ JWTClaimValueTypeStringArray JWTClaimValueType = "StringArray"
+)
+
// AuthorizationAction defines the action to be taken if a rule matches.
// +kubebuilder:validation:Enum=Allow;Deny
type AuthorizationAction string
diff --git a/api/v1alpha1/backend_types.go b/api/v1alpha1/backend_types.go
index 9e28a341ce1..6afbcf9d182 100644
--- a/api/v1alpha1/backend_types.go
+++ b/api/v1alpha1/backend_types.go
@@ -58,7 +58,7 @@ type BackendEndpoint struct {
// +optional
FQDN *FQDNEndpoint `json:"fqdn,omitempty"`
- // IP defines an IP endpoint. Currently, only IPv4 Addresses are supported.
+ // IP defines an IP endpoint. Supports both IPv4 and IPv6 addresses.
//
// +optional
IP *IPEndpoint `json:"ip,omitempty"`
@@ -73,10 +73,11 @@ type BackendEndpoint struct {
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-socketaddress
type IPEndpoint struct {
// Address defines the IP address of the backend endpoint.
+ // Supports both IPv4 and IPv6 addresses.
//
- // +kubebuilder:validation:MinLength=7
- // +kubebuilder:validation:MaxLength=15
- // +kubebuilder:validation:Pattern=`^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`
+ // +kubebuilder:validation:MinLength=3
+ // +kubebuilder:validation:MaxLength=45
+ // +kubebuilder:validation:Pattern=`^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(([0-9a-fA-F]{1,4}:){1,7}[0-9a-fA-F]{1,4}|::|(([0-9a-fA-F]{1,4}:){0,5})?(:[0-9a-fA-F]{1,4}){1,2})$`
Address string `json:"address"`
// Port defines the port of the backend endpoint.
@@ -115,7 +116,7 @@ type BackendSpec struct {
// Endpoints defines the endpoints to be used when connecting to the backend.
//
// +kubebuilder:validation:MinItems=1
- // +kubebuilder:validation:MaxItems=4
+ // +kubebuilder:validation:MaxItems=64
// +kubebuilder:validation:XValidation:rule="self.all(f, has(f.fqdn)) || !self.exists(f, has(f.fqdn))",message="fqdn addresses cannot be mixed with other address types"
Endpoints []BackendEndpoint `json:"endpoints,omitempty"`
@@ -123,6 +124,15 @@ type BackendSpec struct {
//
// +optional
AppProtocols []AppProtocolType `json:"appProtocols,omitempty"`
+
+ // Fallback indicates whether the backend is designated as a fallback.
+ // It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ // when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ // The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ // the health of the active backends falls below 72%.
+ //
+ // +optional
+ Fallback *bool `json:"fallback,omitempty"`
}
// BackendConditionType is a type of condition for a backend. This type should be
diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go
index f484f44b409..4183c12830f 100644
--- a/api/v1alpha1/backendtrafficpolicy_types.go
+++ b/api/v1alpha1/backendtrafficpolicy_types.go
@@ -6,7 +6,6 @@
package v1alpha1
import (
- "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
)
@@ -46,48 +45,18 @@ type BackendTrafficPolicy struct {
// BackendTrafficPolicySpec defines the desired state of BackendTrafficPolicy.
type BackendTrafficPolicySpec struct {
PolicyTargetReferences `json:",inline"`
+ ClusterSettings `json:",inline"`
// RateLimit allows the user to limit the number of incoming requests
// to a predefined value based on attributes within the traffic flow.
// +optional
RateLimit *RateLimitSpec `json:"rateLimit,omitempty"`
- // LoadBalancer policy to apply when routing traffic from the gateway to
- // the backend endpoints
- // +optional
- LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty"`
-
- // ProxyProtocol enables the Proxy Protocol when communicating with the backend.
- // +optional
- ProxyProtocol *ProxyProtocol `json:"proxyProtocol,omitempty"`
-
- // TcpKeepalive settings associated with the upstream client connection.
- // Disabled by default.
- //
- // +optional
- TCPKeepalive *TCPKeepalive `json:"tcpKeepalive,omitempty"`
-
- // HealthCheck allows gateway to perform active health checking on backends.
- //
- // +optional
- HealthCheck *HealthCheck `json:"healthCheck,omitempty"`
-
// FaultInjection defines the fault injection policy to be applied. This configuration can be used to
// inject delays and abort requests to mimic failure scenarios such as service failures and overloads
// +optional
FaultInjection *FaultInjection `json:"faultInjection,omitempty"`
- // Circuit Breaker settings for the upstream connections and requests.
- // If not set, circuit breakers will be enabled with the default thresholds
- //
- // +optional
- CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty"`
-
- // Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
- // If not set, retry will be disabled.
- // +optional
- Retry *Retry `json:"retry,omitempty"`
-
// UseClientProtocol configures Envoy to prefer sending requests to backends using
// the same HTTP protocol that the incoming request used. Defaults to false, which means
// that Envoy will use the protocol indicated by the attached BackendRef.
@@ -95,21 +64,17 @@ type BackendTrafficPolicySpec struct {
// +optional
UseClientProtocol *bool `json:"useClientProtocol,omitempty"`
- // Timeout settings for the backend connections.
- //
- // +optional
- Timeout *Timeout `json:"timeout,omitempty"`
-
// The compression config for the http streams.
//
// +optional
// +notImplementedHide
Compression []*Compression `json:"compression,omitempty"`
- // Connection includes backend connection settings.
+ // ResponseOverride defines the configuration to override specific responses with a custom one.
+ // If multiple configurations are specified, the first one to match wins.
//
// +optional
- Connection *BackendConnection `json:"connection,omitempty"`
+ ResponseOverride []*ResponseOverride `json:"responseOverride,omitempty"`
}
// +kubebuilder:object:root=true
@@ -121,18 +86,6 @@ type BackendTrafficPolicyList struct {
Items []BackendTrafficPolicy `json:"items"`
}
-// BackendTrafficPolicyConnection allows users to configure connection-level settings of backend
-type BackendTrafficPolicyConnection struct {
- // BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
- // If unspecified, an implementation defined default is applied (32768 bytes).
- // For example, 20Mi, 1Gi, 256Ki etc.
- // Note: that when the suffix is not provided, the value is interpreted as bytes.
- //
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="BufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
- // +optional
- BufferLimit *resource.Quantity `json:"bufferLimit,omitempty"`
-}
-
func init() {
SchemeBuilder.Register(&BackendTrafficPolicy{}, &BackendTrafficPolicyList{})
}
diff --git a/api/v1alpha1/basic_auth_types.go b/api/v1alpha1/basic_auth_types.go
index 97fa66d5e76..f7bec283780 100644
--- a/api/v1alpha1/basic_auth_types.go
+++ b/api/v1alpha1/basic_auth_types.go
@@ -5,7 +5,9 @@
package v1alpha1
-import gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
+import (
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+)
const BasicAuthUsersSecretKey = ".htpasswd"
@@ -23,5 +25,5 @@ type BasicAuth struct {
// for more details.
//
// Note: The secret must be in the same namespace as the SecurityPolicy.
- Users gwapiv1b1.SecretObjectReference `json:"users"`
+ Users gwapiv1.SecretObjectReference `json:"users"`
}
diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go
index 397535ebf43..6c7129da060 100644
--- a/api/v1alpha1/clienttrafficpolicy_types.go
+++ b/api/v1alpha1/clienttrafficpolicy_types.go
@@ -6,8 +6,8 @@
package v1alpha1
import (
- "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
)
@@ -135,6 +135,12 @@ type HeaderSettings struct {
//
// +optional
PreserveXRequestID *bool `json:"preserveXRequestID,omitempty"`
+
+ // EarlyRequestHeaders defines settings for early request header modification, before envoy performs
+ // routing, tracing and built-in header manipulation.
+ //
+ // +optional
+ EarlyRequestHeaders *gwapiv1.HTTPHeaderFilter `json:"earlyRequestHeaders,omitempty"`
}
// WithUnderscoresAction configures the action to take when an HTTP header with underscores
@@ -231,14 +237,29 @@ type ClientIPDetectionSettings struct {
}
// XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address.
+// Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
+// for more details.
+// +kubebuilder:validation:XValidation:rule="(has(self.numTrustedHops) && !has(self.trustedCIDRs)) || (!has(self.numTrustedHops) && has(self.trustedCIDRs))", message="only one of numTrustedHops or trustedCIDRs must be set"
type XForwardedForSettings struct {
// NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP
// headers to trust when determining the origin client's IP address.
- // Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
- // for more details.
+ // Only one of NumTrustedHops and TrustedCIDRs must be set.
//
// +optional
NumTrustedHops *uint32 `json:"numTrustedHops,omitempty"`
+
+ // TrustedCIDRs is a list of CIDR ranges to trust when evaluating
+ // the remote IP address to determine the original client’s IP address.
+ // When the remote IP address matches a trusted CIDR and the x-forwarded-for header was sent,
+ // each entry in the x-forwarded-for header is evaluated from right to left
+ // and the first public non-trusted address is used as the original client address.
+ // If all addresses in x-forwarded-for are within the trusted list, the first (leftmost) entry is used.
+ // Only one of NumTrustedHops and TrustedCIDRs must be set.
+ //
+ // +optional
+ // +kubebuilder:validation:MinItems=1
+ // +notImplementedHide
+ TrustedCIDRs []CIDR `json:"trustedCIDRs,omitempty"`
}
// CustomHeaderExtensionSettings provides configuration for determining the client IP address for a request based on
@@ -289,30 +310,6 @@ type HTTP10Settings struct {
UseDefaultHost *bool `json:"useDefaultHost,omitempty"`
}
-// HTTP2Settings provides HTTP/2 configuration on the listener.
-type HTTP2Settings struct {
- // InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
- // If not set, the default value is 64 KiB(64*1024).
- //
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialStreamWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
- // +optional
- InitialStreamWindowSize *resource.Quantity `json:"initialStreamWindowSize,omitempty"`
-
- // InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
- // If not set, the default value is 1 MiB.
- //
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialConnectionWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
- // +optional
- InitialConnectionWindowSize *resource.Quantity `json:"initialConnectionWindowSize,omitempty"`
-
- // MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
- // If not set, the default value is 100.
- // +kubebuilder:validation:Minimum=1
- // +kubebuilder:validation:Maximum=2147483647
- // +optional
- MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty"`
-}
-
// HealthCheckSettings provides HealthCheck configuration on the HTTP/HTTPS listener.
type HealthCheckSettings struct {
// Path specifies the HTTP path to match on for health check requests.
diff --git a/api/v1alpha1/connection_types.go b/api/v1alpha1/connection_types.go
index 758a22fddc7..efb24dc3bb1 100644
--- a/api/v1alpha1/connection_types.go
+++ b/api/v1alpha1/connection_types.go
@@ -17,34 +17,58 @@ type ClientConnection struct {
// +optional
ConnectionLimit *ConnectionLimit `json:"connectionLimit,omitempty"`
// BufferLimit provides configuration for the maximum buffer size in bytes for each incoming connection.
+ // BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
// For example, 20Mi, 1Gi, 256Ki etc.
// Note that when the suffix is not provided, the value is interpreted as bytes.
// Default: 32768 bytes.
//
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="bufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
// +optional
BufferLimit *resource.Quantity `json:"bufferLimit,omitempty"`
+ // SocketBufferLimit provides configuration for the maximum buffer size in bytes for each incoming socket.
+ // SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ // For example, 20Mi, 1Gi, 256Ki etc.
+ // Note that when the suffix is not provided, the value is interpreted as bytes.
+ //
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
+ // +optional
+ // +notImplementedHide
+ SocketBufferLimit *resource.Quantity `json:"socketBufferLimit,omitempty"`
}
// BackendConnection allows users to configure connection-level settings of backend
type BackendConnection struct {
// BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ // BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
// If unspecified, an implementation defined default is applied (32768 bytes).
// For example, 20Mi, 1Gi, 256Ki etc.
// Note: that when the suffix is not provided, the value is interpreted as bytes.
//
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="BufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
// +optional
BufferLimit *resource.Quantity `json:"bufferLimit,omitempty"`
+ // SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ // to backend.
+ // SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ // For example, 20Mi, 1Gi, 256Ki etc.
+ // Note that when the suffix is not provided, the value is interpreted as bytes.
+ //
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
+ // +optional
+ // +notImplementedHide
+ SocketBufferLimit *resource.Quantity `json:"socketBufferLimit,omitempty"`
}
type ConnectionLimit struct {
// Value of the maximum concurrent connections limit.
// When the limit is reached, incoming connections will be closed after the CloseDelay duration.
- // Default: unlimited.
//
- // +kubebuilder:validation:Minimum=0
- Value int64 `json:"value,omitempty"`
+ // +kubebuilder:validation:Minimum=1
+ Value int64 `json:"value"`
// CloseDelay defines the delay to use before closing connections that are rejected
// once the limit value is reached.
diff --git a/api/v1alpha1/cors_types.go b/api/v1alpha1/cors_types.go
index 2c2fb50f681..26c87bd8a05 100644
--- a/api/v1alpha1/cors_types.go
+++ b/api/v1alpha1/cors_types.go
@@ -29,18 +29,48 @@ type Origin string
// CORS defines the configuration for Cross-Origin Resource Sharing (CORS).
type CORS struct {
// AllowOrigins defines the origins that are allowed to make requests.
- // +kubebuilder:validation:MinItems=1
- AllowOrigins []Origin `json:"allowOrigins,omitempty" yaml:"allowOrigins"`
+ // It specifies the allowed origins in the Access-Control-Allow-Origin CORS response header.
+ // The value "*" allows any origin to make requests.
+ //
+ // +optional
+ AllowOrigins []Origin `json:"allowOrigins,omitempty"`
+
// AllowMethods defines the methods that are allowed to make requests.
- // +kubebuilder:validation:MinItems=1
- AllowMethods []string `json:"allowMethods,omitempty" yaml:"allowMethods"`
+ // It specifies the allowed methods in the Access-Control-Allow-Methods CORS response header..
+ // The value "*" allows any method to be used.
+ //
+ // +optional
+ AllowMethods []string `json:"allowMethods,omitempty"`
+
// AllowHeaders defines the headers that are allowed to be sent with requests.
- AllowHeaders []string `json:"allowHeaders,omitempty" yaml:"allowHeaders,omitempty"`
- // ExposeHeaders defines the headers that can be exposed in the responses.
- ExposeHeaders []string `json:"exposeHeaders,omitempty" yaml:"exposeHeaders,omitempty"`
+ // It specifies the allowed headers in the Access-Control-Allow-Headers CORS response header..
+ // The value "*" allows any header to be sent.
+ //
+ // +optional
+ AllowHeaders []string `json:"allowHeaders,omitempty"`
+
+ // ExposeHeaders defines which response headers should be made accessible to
+ // scripts running in the browser.
+ // It specifies the headers in the Access-Control-Expose-Headers CORS response header..
+ // The value "*" allows any header to be exposed.
+ //
+ // +optional
+ ExposeHeaders []string `json:"exposeHeaders,omitempty"`
+
// MaxAge defines how long the results of a preflight request can be cached.
- MaxAge *metav1.Duration `json:"maxAge,omitempty" yaml:"maxAge,omitempty"`
+ // It specifies the value in the Access-Control-Max-Age CORS response header..
+ //
+ // +optional
+ MaxAge *metav1.Duration `json:"maxAge,omitempty"`
+
// AllowCredentials indicates whether a request can include user credentials
// like cookies, authentication headers, or TLS client certificates.
- AllowCredentials *bool `json:"allowCredentials,omitempty" yaml:"allowCredentials,omitempty"`
+ // It specifies the value in the Access-Control-Allow-Credentials CORS response header.
+ //
+ // +optional
+ AllowCredentials *bool `json:"allowCredentials,omitempty"`
+
+ // TODO zhaohuabing: according to CORS spec, wildcard should be treated as a literal value
+ // for CORS requests with credentials.
+ // This needs to be supported in the Envoy CORS filter.
}
diff --git a/api/v1alpha1/dns_types.go b/api/v1alpha1/dns_types.go
new file mode 100644
index 00000000000..62108a934a9
--- /dev/null
+++ b/api/v1alpha1/dns_types.go
@@ -0,0 +1,18 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package v1alpha1
+
+import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+type DNS struct {
+ // DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ // Defaults to 30 seconds.
+ DNSRefreshRate *metav1.Duration `json:"dnsRefreshRate,omitempty"`
+ // RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ // If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ // Defaults to true.
+ RespectDNSTTL *bool `json:"respectDnsTtl,omitempty"`
+}
diff --git a/api/v1alpha1/envoygateway_helpers.go b/api/v1alpha1/envoygateway_helpers.go
index 0b1faf7e66a..68c451e68df 100644
--- a/api/v1alpha1/envoygateway_helpers.go
+++ b/api/v1alpha1/envoygateway_helpers.go
@@ -6,7 +6,8 @@
package v1alpha1
import (
- "fmt"
+ "net"
+ "strconv"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
@@ -80,7 +81,7 @@ func (e *EnvoyGateway) GetEnvoyGatewayAdmin() *EnvoyGatewayAdmin {
func (e *EnvoyGateway) GetEnvoyGatewayAdminAddress() string {
address := e.GetEnvoyGatewayAdmin().Address
if address != nil {
- return fmt.Sprintf("%s:%d", address.Host, address.Port)
+ return net.JoinHostPort(address.Host, strconv.Itoa(address.Port))
}
return ""
@@ -237,9 +238,20 @@ func (r *EnvoyGatewayProvider) GetEnvoyGatewayKubeProvider() *EnvoyGatewayKubern
if r.Kubernetes.ShutdownManager == nil {
r.Kubernetes.ShutdownManager = &ShutdownManager{Image: ptr.To(DefaultShutdownManagerImage)}
}
+
return r.Kubernetes
}
+func (r *EnvoyGatewayProvider) IsRunningOnKubernetes() bool {
+ return r.Type == ProviderTypeKubernetes
+}
+
+func (r *EnvoyGatewayProvider) IsRunningOnHost() bool {
+ return r.Type == ProviderTypeCustom &&
+ r.Custom.Infrastructure != nil &&
+ r.Custom.Infrastructure.Type == InfrastructureProviderTypeHost
+}
+
// DefaultEnvoyGatewayLoggingLevel returns a new EnvoyGatewayLogging with default configuration parameters.
// When v1alpha1.LogComponentGatewayDefault specified, all other logging components are ignored.
func (logging *EnvoyGatewayLogging) DefaultEnvoyGatewayLoggingLevel(level LogLevel) LogLevel {
diff --git a/api/v1alpha1/envoygateway_types.go b/api/v1alpha1/envoygateway_types.go
index 6e84d07ba7e..6cf8e334182 100644
--- a/api/v1alpha1/envoygateway_types.go
+++ b/api/v1alpha1/envoygateway_types.go
@@ -174,7 +174,7 @@ type ExtensionAPISettings struct {
// EnvoyGatewayProvider defines the desired configuration of a provider.
// +union
type EnvoyGatewayProvider struct {
- // Type is the type of provider to use. Supported types are "Kubernetes".
+ // Type is the type of provider to use. Supported types are "Kubernetes", "Custom".
//
// +unionDiscriminator
Type ProviderType `json:"type"`
@@ -186,7 +186,7 @@ type EnvoyGatewayProvider struct {
Kubernetes *EnvoyGatewayKubernetesProvider `json:"kubernetes,omitempty"`
// Custom defines the configuration for the Custom provider. This provider
- // allows you to define a specific resource provider and a infrastructure
+ // allows you to define a specific resource provider and an infrastructure
// provider.
//
// +optional
@@ -271,7 +271,11 @@ type EnvoyGatewayCustomProvider struct {
// This provider is used to specify the provider to be used
// to provide an environment to deploy the out resources like
// the Envoy Proxy data plane.
- Infrastructure EnvoyGatewayInfrastructureProvider `json:"infrastructure"`
+ //
+ // Infrastructure is optional, if provider is not specified,
+ // No infrastructure provider is available.
+ // +optional
+ Infrastructure *EnvoyGatewayInfrastructureProvider `json:"infrastructure,omitempty"`
}
// ResourceProviderType defines the types of custom resource providers supported by Envoy Gateway.
@@ -300,7 +304,7 @@ type EnvoyGatewayResourceProvider struct {
// EnvoyGatewayFileResourceProvider defines configuration for the File Resource provider.
type EnvoyGatewayFileResourceProvider struct {
// Paths are the paths to a directory or file containing the resource configuration.
- // Recursive sub directories are not currently supported.
+ // Recursive subdirectories are not currently supported.
Paths []string `json:"paths"`
}
diff --git a/api/v1alpha1/envoypatchpolicy_types.go b/api/v1alpha1/envoypatchpolicy_types.go
index 22effb69756..a7ac8992dbc 100644
--- a/api/v1alpha1/envoypatchpolicy_types.go
+++ b/api/v1alpha1/envoypatchpolicy_types.go
@@ -109,9 +109,18 @@ type JSONPatchOperationType string
type JSONPatchOperation struct {
// Op is the type of operation to perform
Op JSONPatchOperationType `json:"op"`
- // Path is the location of the target document/field where the operation will be performed
- // Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
- Path string `json:"path"`
+ // Path is a JSONPointer expression. Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
+ // It specifies the location of the target document/field where the operation will be performed
+ // +optional
+ Path *string `json:"path,omitempty"`
+ // JSONPath is a JSONPath expression. Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details.
+ // It produces one or more JSONPointer expressions based on the given JSON document.
+ // If no JSONPointer is found, it will result in an error.
+ // If the 'Path' property is also set, it will be appended to the resulting JSONPointer expressions from the JSONPath evaluation.
+ // This is useful when creating a property that does not yet exist in the JSON document.
+ // The final JSONPointer expressions specifies the locations in the target document/field where the operation will be applied.
+ // +optional
+ JSONPath *string `json:"jsonPath,omitempty"`
// From is the source location of the value to be copied or moved. Only valid
// for move or copy operations
// Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
diff --git a/api/v1alpha1/envoyproxy_metric_types.go b/api/v1alpha1/envoyproxy_metric_types.go
index 8791ddbd490..f3fe7c3a5c0 100644
--- a/api/v1alpha1/envoyproxy_metric_types.go
+++ b/api/v1alpha1/envoyproxy_metric_types.go
@@ -15,6 +15,7 @@ type ProxyMetrics struct {
// Prometheus defines the configuration for Admin endpoint `/stats/prometheus`.
Prometheus *ProxyPrometheusProvider `json:"prometheus,omitempty"`
// Sinks defines the metric sinks where metrics are sent to.
+ // +kubebuilder:validation:MaxItems=16
Sinks []ProxyMetricSink `json:"sinks,omitempty"`
// Matches defines configuration for selecting specific metrics instead of generating all metrics stats
// that are enabled by default. This helps reduce CPU and memory overhead in Envoy, but eliminating some stats
@@ -26,11 +27,20 @@ type ProxyMetrics struct {
Matches []StringMatch `json:"matches,omitempty"`
// EnableVirtualHostStats enables envoy stat metrics for virtual hosts.
- EnableVirtualHostStats bool `json:"enableVirtualHostStats,omitempty"`
+ //
+ // +optional
+ EnableVirtualHostStats *bool `json:"enableVirtualHostStats,omitempty"`
// EnablePerEndpointStats enables per endpoint envoy stats metrics.
// Please use with caution.
- EnablePerEndpointStats bool `json:"enablePerEndpointStats,omitempty"`
+ //
+ // +optional
+ EnablePerEndpointStats *bool `json:"enablePerEndpointStats,omitempty"`
+
+ // EnableRequestResponseSizesStats enables publishing of histograms tracking header and body sizes of requests and responses.
+ //
+ // +optional
+ EnableRequestResponseSizesStats *bool `json:"enableRequestResponseSizesStats,omitempty"`
}
// ProxyMetricSink defines the sink of metrics.
@@ -54,7 +64,11 @@ type ProxyMetricSink struct {
// ProxyOpenTelemetrySink defines the configuration for OpenTelemetry sink.
//
// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true"
type ProxyOpenTelemetrySink struct {
+ BackendCluster `json:",inline"`
// Host define the service hostname.
// Deprecated: Use BackendRefs instead.
//
@@ -68,15 +82,6 @@ type ProxyOpenTelemetrySink struct {
// +kubebuilder:validation:Maximum=65535
// +kubebuilder:default=4317
Port int32 `json:"port,omitempty"`
- // BackendRefs references a Kubernetes object that represents the
- // backend server to which the metric will be sent.
- // Only Service kind is supported for now.
- //
- // +optional
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs,omitempty"`
// TODO: add support for customizing OpenTelemetry sink in https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto#envoy-v3-api-msg-extensions-stat-sinks-open-telemetry-v3-sinkconfig
}
diff --git a/api/v1alpha1/envoyproxy_types.go b/api/v1alpha1/envoyproxy_types.go
index 910c6d1503a..cbf2c9226d0 100644
--- a/api/v1alpha1/envoyproxy_types.go
+++ b/api/v1alpha1/envoyproxy_types.go
@@ -112,6 +112,8 @@ type EnvoyProxySpec struct {
//
// - envoy.filters.http.jwt_authn
//
+ // - envoy.filters.http.stateful_session
+ //
// - envoy.filters.http.ext_proc
//
// - envoy.filters.http.wasm
@@ -122,6 +124,8 @@ type EnvoyProxySpec struct {
//
// - envoy.filters.http.ratelimit
//
+ // - envoy.filters.http.custom_response
+ //
// - envoy.filters.http.router
//
// Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain.
@@ -132,6 +136,17 @@ type EnvoyProxySpec struct {
// These settings are applied on backends for which TLS policies are specified.
// +optional
BackendTLS *BackendTLSConfig `json:"backendTLS,omitempty"`
+
+ // IPFamily specifies the IP family for the EnvoyProxy fleet.
+ // This setting only affects the Gateway listener port and does not impact
+ // other aspects of the Envoy proxy configuration.
+ // If not specified, the system will operate as follows:
+ // - It defaults to IPv4 only.
+ // - IPv6 and dual-stack environments are not supported in this default configuration.
+ // Note: To enable IPv6 or dual-stack functionality, explicit configuration is required.
+ // +kubebuilder:validation:Enum=IPv4;IPv6;DualStack
+ // +optional
+ IPFamily *IPFamily `json:"ipFamily,omitempty"`
}
// RoutingType defines the type of routing of this Envoy proxy.
@@ -172,7 +187,7 @@ type FilterPosition struct {
}
// EnvoyFilter defines the type of Envoy HTTP filter.
-// +kubebuilder:validation:Enum=envoy.filters.http.health_check;envoy.filters.http.fault;envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_auth;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.ext_proc;envoy.filters.http.wasm;envoy.filters.http.rbac;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit
+// +kubebuilder:validation:Enum=envoy.filters.http.health_check;envoy.filters.http.fault;envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_auth;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.stateful_session;envoy.filters.http.ext_proc;envoy.filters.http.wasm;envoy.filters.http.rbac;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit;envoy.filters.http.custom_response
type EnvoyFilter string
const (
@@ -197,6 +212,9 @@ const (
// EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter.
EnvoyFilterJWTAuthn EnvoyFilter = "envoy.filters.http.jwt_authn"
+ // EnvoyFilterSessionPersistence defines the Envoy HTTP session persistence filter.
+ EnvoyFilterSessionPersistence EnvoyFilter = "envoy.filters.http.stateful_session"
+
// EnvoyFilterExtProc defines the Envoy HTTP external process filter.
EnvoyFilterExtProc EnvoyFilter = "envoy.filters.http.ext_proc"
@@ -212,6 +230,9 @@ const (
// EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter.
EnvoyFilterRateLimit EnvoyFilter = "envoy.filters.http.ratelimit"
+ // EnvoyFilterCustomResponse defines the Envoy HTTP custom response filter.
+ EnvoyFilterCustomResponse EnvoyFilter = "envoy.filters.http.custom_response"
+
// EnvoyFilterRouter defines the Envoy HTTP router filter.
EnvoyFilterRouter EnvoyFilter = "envoy.filters.http.router"
)
@@ -251,12 +272,12 @@ type EnvoyProxyProvider struct {
// ShutdownConfig defines configuration for graceful envoy shutdown process.
type ShutdownConfig struct {
// DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds.
- // If unspecified, defaults to 600 seconds.
+ // If unspecified, defaults to 60 seconds.
//
// +optional
DrainTimeout *metav1.Duration `json:"drainTimeout,omitempty"`
// MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
- // If unspecified, defaults to 5 seconds.
+ // If unspecified, defaults to 10 seconds.
//
// +optional
MinDrainDuration *metav1.Duration `json:"minDrainDuration,omitempty"`
@@ -353,19 +374,27 @@ const (
)
// ProxyBootstrap defines Envoy Bootstrap configuration.
+// +union
+// +kubebuilder:validation:XValidation:rule="self.type == 'JSONPatch' ? self.jsonPatches.size() > 0 : has(self.value)", message="provided bootstrap patch doesn't match the configured patch type"
type ProxyBootstrap struct {
- // Type is the type of the bootstrap configuration, it should be either Replace or Merge.
+ // Type is the type of the bootstrap configuration, it should be either Replace, Merge, or JSONPatch.
// If unspecified, it defaults to Replace.
// +optional
// +kubebuilder:default=Replace
+ // +unionDiscriminator
Type *BootstrapType `json:"type"`
// Value is a YAML string of the bootstrap.
- Value string `json:"value"`
+ // +optional
+ Value *string `json:"value,omitempty"`
+
+ // JSONPatches is an array of JSONPatches to be applied to the default bootstrap. Patches are
+ // applied in the order in which they are defined.
+ JSONPatches []JSONPatchOperation `json:"jsonPatches,omitempty"`
}
// BootstrapType defines the types of bootstrap supported by Envoy Gateway.
-// +kubebuilder:validation:Enum=Merge;Replace
+// +kubebuilder:validation:Enum=Merge;Replace;JSONPatch
type BootstrapType string
const (
@@ -376,6 +405,9 @@ const (
// Replace replaces the default bootstrap with the provided one.
BootstrapTypeReplace BootstrapType = "Replace"
+
+ // JSONPatch applies the provided JSONPatches to the default bootstrap.
+ BootstrapTypeJSONPatch BootstrapType = "JSONPatch"
)
// EnvoyProxyStatus defines the observed state of EnvoyProxy. This type is not implemented
@@ -394,6 +426,20 @@ type EnvoyProxyList struct {
Items []EnvoyProxy `json:"items"`
}
+// IPFamily defines the IP family to use for the Envoy proxy.
+type IPFamily string
+
+const (
+ // IPv4 defines the IPv4 family.
+ IPv4 IPFamily = "IPv4"
+ // IPv6 defines the IPv6 family.
+ IPv6 IPFamily = "IPv6"
+ // DualStack defines the dual-stack family.
+ // When set to DualStack, Envoy proxy will listen on both IPv4 and IPv6 addresses
+ // for incoming client traffic, enabling support for both IP protocol versions.
+ DualStack IPFamily = "DualStack"
+)
+
func init() {
SchemeBuilder.Register(&EnvoyProxy{}, &EnvoyProxyList{})
}
diff --git a/api/v1alpha1/ext_auth_types.go b/api/v1alpha1/ext_auth_types.go
index 13de5f9f6ac..16652c9fd28 100644
--- a/api/v1alpha1/ext_auth_types.go
+++ b/api/v1alpha1/ext_auth_types.go
@@ -5,18 +5,10 @@
package v1alpha1
-import (
- gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
-)
-
// ExtAuth defines the configuration for External Authorization.
//
// +kubebuilder:validation:XValidation:rule="(has(self.grpc) || has(self.http))",message="one of grpc or http must be specified"
// +kubebuilder:validation:XValidation:rule="(has(self.grpc) && !has(self.http)) || (!has(self.grpc) && has(self.http))",message="only one of grpc or http can be specified"
-// +kubebuilder:validation:XValidation:rule="has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.group) || self.grpc.backendRef.group == \"\") : true", message="group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) is supported"
-// +kubebuilder:validation:XValidation:rule="has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.kind) || self.grpc.backendRef.kind == 'Service') : true", message="kind is invalid, only Service (specified by omitting the kind field or setting it to 'Service') is supported"
-// +kubebuilder:validation:XValidation:rule="has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.group) || self.http.backendRef.group == \"\") : true", message="group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) is supported"
-// +kubebuilder:validation:XValidation:rule="has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.kind) || self.http.backendRef.kind == 'Service') : true", message="kind is invalid, only Service (specified by omitting the kind field or setting it to 'Service') is supported"
type ExtAuth struct {
// GRPC defines the gRPC External Authorization service.
// Either GRPCService or HTTPService must be specified,
@@ -41,6 +33,10 @@ type ExtAuth struct {
// +optional
HeadersToExtAuth []string `json:"headersToExtAuth,omitempty"`
+ // BodyToExtAuth defines the Body to Ext Auth configuration.
+ // +optional
+ BodyToExtAuth *BodyToExtAuth `json:"bodyToExtAuth,omitempty"`
+
// FailOpen is a switch used to control the behavior when a response from the External Authorization service cannot be obtained.
// If FailOpen is set to true, the system allows the traffic to pass through.
// Otherwise, if it is set to false or not set (defaulting to false),
@@ -50,51 +46,35 @@ type ExtAuth struct {
// +optional
// +kubebuilder:default=false
FailOpen *bool `json:"failOpen,omitempty"`
+
+ // RecomputeRoute clears the route cache and recalculates the routing decision.
+ // This field must be enabled if the headers added or modified by the ExtAuth are used for
+ // route matching decisions. If the recomputation selects a new route, features targeting
+ // the new matched route will be applied.
+ //
+ // +optional
+ RecomputeRoute *bool `json:"recomputeRoute,omitempty"`
}
// GRPCExtAuthService defines the gRPC External Authorization service
// The authorization request message is defined in
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto
// +kubebuilder:validation:XValidation:message="backendRef or backendRefs needs to be set",rule="has(self.backendRef) || self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service' || f.kind == 'Backend') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\" || f.group == 'gateway.envoyproxy.io')) : true"
type GRPCExtAuthService struct {
- // BackendRef references a Kubernetes object that represents the
- // backend server to which the authorization request will be sent.
// Only Service kind is supported for now.
- //
- // Deprecated: Use BackendRefs instead.
- BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"`
-
- // BackendRefs references a Kubernetes object that represents the
- // backend server to which the authorization request will be sent.
- // Only Service kind is supported for now.
- //
- // +optional
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs,omitempty"`
+ BackendCluster `json:",inline"`
}
// HTTPExtAuthService defines the HTTP External Authorization service
//
// +kubebuilder:validation:XValidation:message="backendRef or backendRefs needs to be set",rule="has(self.backendRef) || self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service' || f.kind == 'Backend') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\" || f.group == 'gateway.envoyproxy.io')) : true"
type HTTPExtAuthService struct {
- // BackendRef references a Kubernetes object that represents the
- // backend server to which the authorization request will be sent.
// Only Service kind is supported for now.
- //
- // Deprecated: Use BackendRefs instead.
- BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"`
-
- // BackendRefs references a Kubernetes object that represents the
- // backend server to which the authorization request will be sent.
- // Only Service kind is supported for now.
- //
- // +optional
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs,omitempty"`
+ BackendCluster `json:",inline"`
// Path is the path of the HTTP External Authorization service.
// If path is specified, the authorization request will be sent to that path,
@@ -109,3 +89,14 @@ type HTTPExtAuthService struct {
// +optional
HeadersToBackend []string `json:"headersToBackend,omitempty"`
}
+
+// BodyToExtAuth defines the Body to Ext Auth configuration
+type BodyToExtAuth struct {
+ // MaxRequestBytes is the maximum size of a message body that the filter will hold in memory.
+ // Envoy will return HTTP 413 and will not initiate the authorization process when buffer
+ // reaches the number set in this field.
+ // Note that this setting will have precedence over failOpen mode.
+ //
+ // +kubebuilder:validation:Minimum=1
+ MaxRequestBytes uint32 `json:"maxRequestBytes"`
+}
diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go
index 27be5e6318d..ca78b619c4d 100644
--- a/api/v1alpha1/ext_proc_types.go
+++ b/api/v1alpha1/ext_proc_types.go
@@ -22,11 +22,21 @@ const (
)
// ProcessingModeOptions defines if headers or body should be processed by the external service
+// and which attributes are sent to the processor
type ProcessingModeOptions struct {
// Defines body processing mode
//
// +optional
Body *ExtProcBodyProcessingMode `json:"body,omitempty"`
+
+ // Defines which attributes are sent to the external processor. Envoy Gateway currently
+ // supports only the following attribute prefixes: connection, source, destination,
+ // request, response, upstream and xds.route.
+ // https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/advanced/attributes
+ //
+ // +optional
+ // +kubebuilder:validation:items:Pattern=`^(connection\.|source\.|destination\.|request\.|response\.|upstream\.|xds\.route_)[a-z_1-9]*$`
+ Attributes []string `json:"attributes,omitempty"`
}
// ExtProcProcessingMode defines if and how headers and bodies are sent to the service.
@@ -46,14 +56,11 @@ type ExtProcProcessingMode struct {
}
// ExtProc defines the configuration for External Processing filter.
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service' || f.kind == 'Backend') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\" || f.group == 'gateway.envoyproxy.io')) : true"
type ExtProc struct {
- // BackendRefs defines the configuration of the external processing service
- //
- // +kubebuilder:validation:MinItems=1
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="self.all(f, f.kind == 'Service' || f.kind == 'Backend')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="self.all(f, f.group == '' || f.group == 'gateway.envoyproxy.io')"
- BackendRefs []BackendRef `json:"backendRefs"`
+ BackendCluster `json:",inline"`
// MessageTimeout is the timeout for a response to be returned from the external processor
// Default: 200ms
diff --git a/api/v1alpha1/healthcheck_types.go b/api/v1alpha1/healthcheck_types.go
index cea83d2f5a1..990c95f141a 100644
--- a/api/v1alpha1/healthcheck_types.go
+++ b/api/v1alpha1/healthcheck_types.go
@@ -74,6 +74,7 @@ type PassiveHealthCheck struct {
//
// +kubebuilder:validation:XValidation:rule="self.type == 'HTTP' ? has(self.http) : !has(self.http)",message="If Health Checker type is HTTP, http field needs to be set."
// +kubebuilder:validation:XValidation:rule="self.type == 'TCP' ? has(self.tcp) : !has(self.tcp)",message="If Health Checker type is TCP, tcp field needs to be set."
+// +kubebuilder:validation:XValidation:rule="has(self.grpc) ? self.type == 'GRPC' : true", message="The grpc field can only be set if the Health Checker type is GRPC."
type ActiveHealthCheck struct {
// Timeout defines the time to wait for a health check response.
//
@@ -104,7 +105,7 @@ type ActiveHealthCheck struct {
HealthyThreshold *uint32 `json:"healthyThreshold"`
// Type defines the type of health checker.
- // +kubebuilder:validation:Enum=HTTP;TCP
+ // +kubebuilder:validation:Enum=HTTP;TCP;GRPC
// +unionDiscriminator
Type ActiveHealthCheckerType `json:"type" yaml:"type"`
@@ -117,10 +118,15 @@ type ActiveHealthCheck struct {
// It's required while the health checker type is TCP.
// +optional
TCP *TCPActiveHealthChecker `json:"tcp,omitempty" yaml:"tcp,omitempty"`
+
+ // GRPC defines the configuration of the GRPC health checker.
+ // It's optional, and can only be used if the specified type is GRPC.
+ // +optional
+ GRPC *GRPCActiveHealthChecker `json:"grpc,omitempty" yaml:"grpc,omitempty"`
}
// ActiveHealthCheckerType is the type of health checker.
-// +kubebuilder:validation:Enum=HTTP;TCP
+// +kubebuilder:validation:Enum=HTTP;TCP;GRPC
type ActiveHealthCheckerType string
const (
@@ -128,6 +134,8 @@ const (
ActiveHealthCheckerTypeHTTP ActiveHealthCheckerType = "HTTP"
// ActiveHealthCheckerTypeTCP defines the TCP type of health checking.
ActiveHealthCheckerTypeTCP ActiveHealthCheckerType = "TCP"
+ // ActiveHealthCheckerTypeGRPC defines the GRPC type of health checking.
+ ActiveHealthCheckerTypeGRPC ActiveHealthCheckerType = "GRPC"
)
// HTTPActiveHealthChecker defines the settings of http health check.
@@ -159,6 +167,15 @@ type TCPActiveHealthChecker struct {
Receive *ActiveHealthCheckPayload `json:"receive,omitempty" yaml:"receive,omitempty"`
}
+// GRPCActiveHealthChecker defines the settings of the GRPC health check.
+type GRPCActiveHealthChecker struct {
+ // Service to send in the health check request.
+ // If this is not specified, then the health check request applies to the entire
+ // server and not to a specific service.
+ // +optional
+ Service *string `json:"service,omitempty" yaml:"service,omitempty"`
+}
+
// ActiveHealthCheckPayloadType is the type of the payload.
// +kubebuilder:validation:Enum=Text;Binary
type ActiveHealthCheckPayloadType string
diff --git a/api/v1alpha1/httproutefilter_types.go b/api/v1alpha1/httproutefilter_types.go
new file mode 100644
index 00000000000..3259fabc8f4
--- /dev/null
+++ b/api/v1alpha1/httproutefilter_types.go
@@ -0,0 +1,154 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package v1alpha1
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+const (
+ // KindHTTPRouteFilter is the name of the HTTPRouteFilter kind.
+ KindHTTPRouteFilter = "HTTPRouteFilter"
+)
+
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:categories=envoy-gateway,shortName=hrf
+// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
+
+// HTTPRouteFilter is a custom Envoy Gateway HTTPRouteFilter which provides extended
+// traffic processing options such as path regex rewrite, direct response and more.
+type HTTPRouteFilter struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ // Spec defines the desired state of HTTPRouteFilter.
+ Spec HTTPRouteFilterSpec `json:"spec"`
+}
+
+// HTTPRouteFilterSpec defines the desired state of HTTPRouteFilter.
+// +union
+type HTTPRouteFilterSpec struct {
+ // +optional
+ URLRewrite *HTTPURLRewriteFilter `json:"urlRewrite,omitempty"`
+ // +optional
+ DirectResponse *HTTPDirectResponseFilter `json:"directResponse,omitempty"`
+}
+
+// HTTPURLRewriteFilter define rewrites of HTTP URL components such as path and host
+type HTTPURLRewriteFilter struct {
+ // Hostname is the value to be used to replace the Host header value during
+ // forwarding.
+ //
+ // +optional
+ Hostname *HTTPHostnameModifier `json:"hostname,omitempty"`
+ // Path defines a path rewrite.
+ //
+ // +optional
+ Path *HTTPPathModifier `json:"path,omitempty"`
+}
+
+// HTTPDirectResponseFilter defines the configuration to return a fixed response.
+type HTTPDirectResponseFilter struct {
+ // Content Type of the response. This will be set in the Content-Type header.
+ //
+ // +optional
+ ContentType *string `json:"contentType,omitempty"`
+
+ // Body of the Response
+ //
+ // +optional
+ Body *CustomResponseBody `json:"body,omitempty"`
+
+ // Status Code of the HTTP response
+ // If unset, defaults to 200.
+ // +optional
+ StatusCode *int `json:"statusCode,omitempty"`
+}
+
+// HTTPPathModifierType defines the type of path redirect or rewrite.
+type HTTPPathModifierType string
+
+const (
+ // RegexHTTPPathModifier This type of modifier indicates that the portions of the path that match the specified
+ // regex would be substituted with the specified substitution value
+ // https://www.envoyproxy.io/docs/envoy/latest/api-v3/type/matcher/v3/regex.proto#type-matcher-v3-regexmatchandsubstitute
+ RegexHTTPPathModifier HTTPPathModifierType = "ReplaceRegexMatch"
+)
+
+// HTTPPathModifierType defines the type of Hostname rewrite.
+type HTTPHostnameModifierType string
+
+const (
+ // HeaderHTTPHostnameModifier indicates that the Host header value would be replaced with the value of the header specified in header.
+ // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-header
+ HeaderHTTPHostnameModifier HTTPHostnameModifierType = "Header"
+ // BackendHTTPHostnameModifier indicates that the Host header value would be replaced by the DNS name of the backend if it exists.
+ // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-auto-host-rewrite
+ BackendHTTPHostnameModifier HTTPHostnameModifierType = "Backend"
+)
+
+type ReplaceRegexMatch struct {
+ // Pattern matches a regular expression against the value of the HTTP Path.The regex string must
+ // adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax.
+ // +kubebuilder:validation:MinLength=1
+ Pattern string `json:"pattern"`
+ // Substitution is an expression that replaces the matched portion.The expression may include numbered
+ // capture groups that adhere to syntax documented in https://github.com/google/re2/wiki/Syntax.
+ Substitution string `json:"substitution"`
+}
+
+// +kubebuilder:validation:XValidation:rule="self.type == 'ReplaceRegexMatch' ? has(self.replaceRegexMatch) : !has(self.replaceRegexMatch)",message="If HTTPPathModifier type is ReplaceRegexMatch, replaceRegexMatch field needs to be set."
+type HTTPPathModifier struct {
+ // +kubebuilder:validation:Enum=ReplaceRegexMatch
+ // +kubebuilder:validation:Required
+ Type HTTPPathModifierType `json:"type"`
+ // ReplaceRegexMatch defines a path regex rewrite. The path portions matched by the regex pattern are replaced by the defined substitution.
+ // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-regex-rewrite
+ // Some examples:
+ // (1) replaceRegexMatch:
+ // pattern: ^/service/([^/]+)(/.*)$
+ // substitution: \2/instance/\1
+ // Would transform /service/foo/v1/api into /v1/api/instance/foo.
+ // (2) replaceRegexMatch:
+ // pattern: one
+ // substitution: two
+ // Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/two/zzz.
+ // (3) replaceRegexMatch:
+ // pattern: ^(.*?)one(.*)$
+ // substitution: \1two\2
+ // Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/one/zzz.
+ // (3) replaceRegexMatch:
+ // pattern: (?i)/xxx/
+ // substitution: /yyy/
+ // Would transform path /aaa/XxX/bbb into /aaa/yyy/bbb (case-insensitive).
+ // +optional
+ ReplaceRegexMatch *ReplaceRegexMatch `json:"replaceRegexMatch,omitempty"`
+}
+
+// +kubebuilder:validation:XValidation:message="header must be nil if the type is not Header",rule="!(has(self.header) && self.type != 'Header')"
+// +kubebuilder:validation:XValidation:message="header must be specified for Header type",rule="!(!has(self.header) && self.type == 'Header')"
+type HTTPHostnameModifier struct {
+ // +kubebuilder:validation:Enum=Header;Backend
+ // +kubebuilder:validation:Required
+ Type HTTPHostnameModifierType `json:"type"`
+
+ // Header is the name of the header whose value would be used to rewrite the Host header
+ // +optional
+ Header *string `json:"header,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+
+// HTTPRouteFilterList contains a list of HTTPRouteFilter resources.
+type HTTPRouteFilterList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []HTTPRouteFilter `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&HTTPRouteFilter{}, &HTTPRouteFilterList{})
+}
diff --git a/api/v1alpha1/kubernetes_helpers.go b/api/v1alpha1/kubernetes_helpers.go
index 1ac790b9c13..6dd6b5fbfcc 100644
--- a/api/v1alpha1/kubernetes_helpers.go
+++ b/api/v1alpha1/kubernetes_helpers.go
@@ -11,7 +11,9 @@ import (
jsonpatch "github.com/evanphx/json-patch"
appsv1 "k8s.io/api/apps/v1"
+ autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
+ policyv1 "k8s.io/api/policy/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/utils/ptr"
@@ -237,10 +239,10 @@ func (service *KubernetesServiceSpec) ApplyMergePatch(old *corev1.Service) (*cor
var patchedJSON []byte
var err error
- // Serialize the current deployment to JSON
+ // Serialize the current service to JSON
originalJSON, err := json.Marshal(old)
if err != nil {
- return nil, fmt.Errorf("error marshaling original deployment: %w", err)
+ return nil, fmt.Errorf("error marshaling original service: %w", err)
}
switch {
@@ -263,3 +265,75 @@ func (service *KubernetesServiceSpec) ApplyMergePatch(old *corev1.Service) (*cor
return &patchedService, nil
}
+
+// ApplyMergePatch applies a merge patch to a HorizontalPodAutoscaler based on the merge type
+func (hpa *KubernetesHorizontalPodAutoscalerSpec) ApplyMergePatch(old *autoscalingv2.HorizontalPodAutoscaler) (*autoscalingv2.HorizontalPodAutoscaler, error) {
+ if hpa.Patch == nil {
+ return old, nil
+ }
+
+ var patchedJSON []byte
+ var err error
+
+ // Serialize the current HPA to JSON
+ originalJSON, err := json.Marshal(old)
+ if err != nil {
+ return nil, fmt.Errorf("error marshaling original HorizontalPodAutoscaler: %w", err)
+ }
+
+ switch {
+ case hpa.Patch.Type == nil || *hpa.Patch.Type == StrategicMerge:
+ patchedJSON, err = strategicpatch.StrategicMergePatch(originalJSON, hpa.Patch.Value.Raw, autoscalingv2.HorizontalPodAutoscaler{})
+ case *hpa.Patch.Type == JSONMerge:
+ patchedJSON, err = jsonpatch.MergePatch(originalJSON, hpa.Patch.Value.Raw)
+ default:
+ return nil, fmt.Errorf("unsupported merge type: %s", *hpa.Patch.Type)
+ }
+ if err != nil {
+ return nil, fmt.Errorf("error applying merge patch: %w", err)
+ }
+
+ // Deserialize the patched JSON into a new HorizontalPodAutoscaler object
+ var patchedHpa autoscalingv2.HorizontalPodAutoscaler
+ if err := json.Unmarshal(patchedJSON, &patchedHpa); err != nil {
+ return nil, fmt.Errorf("error unmarshaling patched HorizontalPodAutoscaler: %w", err)
+ }
+
+ return &patchedHpa, nil
+}
+
+// ApplyMergePatch applies a merge patch to a PodDisruptionBudget based on the merge type
+func (pdb *KubernetesPodDisruptionBudgetSpec) ApplyMergePatch(old *policyv1.PodDisruptionBudget) (*policyv1.PodDisruptionBudget, error) {
+ if pdb.Patch == nil {
+ return old, nil
+ }
+
+ var patchedJSON []byte
+ var err error
+
+ // Serialize the PDB deployment to JSON
+ originalJSON, err := json.Marshal(old)
+ if err != nil {
+ return nil, fmt.Errorf("error marshaling original PodDisruptionBudget: %w", err)
+ }
+
+ switch {
+ case pdb.Patch.Type == nil || *pdb.Patch.Type == StrategicMerge:
+ patchedJSON, err = strategicpatch.StrategicMergePatch(originalJSON, pdb.Patch.Value.Raw, policyv1.PodDisruptionBudget{})
+ case *pdb.Patch.Type == JSONMerge:
+ patchedJSON, err = jsonpatch.MergePatch(originalJSON, pdb.Patch.Value.Raw)
+ default:
+ return nil, fmt.Errorf("unsupported merge type: %s", *pdb.Patch.Type)
+ }
+ if err != nil {
+ return nil, fmt.Errorf("error applying merge patch: %w", err)
+ }
+
+ // Deserialize the patched JSON into a new HorizontalPodAutoscaler object
+ var patchedPdb policyv1.PodDisruptionBudget
+ if err := json.Unmarshal(patchedJSON, &patchedPdb); err != nil {
+ return nil, fmt.Errorf("error unmarshaling patched PodDisruptionBudget: %w", err)
+ }
+
+ return &patchedPdb, nil
+}
diff --git a/api/v1alpha1/oidc_types.go b/api/v1alpha1/oidc_types.go
index 53490a1f109..8591cc20f0d 100644
--- a/api/v1alpha1/oidc_types.go
+++ b/api/v1alpha1/oidc_types.go
@@ -7,7 +7,7 @@ package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)
const OIDCClientSecretKey = "client-secret"
@@ -29,7 +29,7 @@ type OIDC struct {
// This is an Opaque secret. The client secret should be stored in the key
// "client-secret".
// +kubebuilder:validation:Required
- ClientSecret gwapiv1b1.SecretObjectReference `json:"clientSecret"`
+ ClientSecret gwapiv1.SecretObjectReference `json:"clientSecret"`
// The optional cookie name overrides to be used for Bearer and IdToken cookies in the
// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
@@ -37,6 +37,14 @@ type OIDC struct {
// +optional
CookieNames *OIDCCookieNames `json:"cookieNames,omitempty"`
+ // The optional domain to set the access and ID token cookies on.
+ // If not set, the cookies will default to the host of the request, not including the subdomains.
+ // If set, the cookies will be set on the specified domain and all subdomains.
+ // This means that requests to any subdomain will not require reauthentication after users log in to the parent domain.
+ // +optional
+ // +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9]))*$`
+ CookieDomain *string `json:"cookieDomain,omitempty"`
+
// The OIDC scopes to be used in the
// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
// The "openid" scope is always added to the list of scopes if not already
@@ -97,7 +105,21 @@ type OIDC struct {
}
// OIDCProvider defines the OIDC Provider configuration.
+// +kubebuilder:validation:XValidation:rule="!has(self.backendRef)",message="BackendRefs must be used, backendRef is not supported."
+// +kubebuilder:validation:XValidation:rule="has(self.backendSettings)? (has(self.backendSettings.retry)?(has(self.backendSettings.retry.perRetry)? !has(self.backendSettings.retry.perRetry.timeout):true):true):true",message="Retry timeout is not supported."
+// +kubebuilder:validation:XValidation:rule="has(self.backendSettings)? (has(self.backendSettings.retry)?(has(self.backendSettings.retry.retryOn)? !has(self.backendSettings.retry.retryOn.httpStatusCodes):true):true):true",message="HTTPStatusCodes is not supported."
type OIDCProvider struct {
+ // BackendRefs is used to specify the address of the OIDC Provider.
+ // If the BackendRefs is not specified, The host and port of the OIDC Provider's token endpoint
+ // will be used as the address of the OIDC Provider.
+ //
+ // TLS configuration can be specified in a BackendTLSConfig resource and target the BackendRefs.
+ //
+ // Other settings for the connection to the OIDC Provider can be specified in the BackendSettings resource.
+ //
+ // +optional
+ BackendCluster `json:",inline"`
+
// The OIDC Provider's [issuer identifier](https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery).
// Issuer MUST be a URI RFC 3986 [RFC3986] with a scheme component that MUST
// be https, a host component, and optionally, port and path components and
diff --git a/api/v1alpha1/ratelimit_types.go b/api/v1alpha1/ratelimit_types.go
index 9228e7d4b87..72382d699f1 100644
--- a/api/v1alpha1/ratelimit_types.go
+++ b/api/v1alpha1/ratelimit_types.go
@@ -101,8 +101,6 @@ type RateLimitSelectCondition struct {
// meaning, a request MUST match all the specified headers.
// At least one of headers or sourceCIDR condition must be specified.
//
- // +listType=map
- // +listMapKey=name
// +optional
// +kubebuilder:validation:MaxItems=16
Headers []HeaderMatch `json:"headers,omitempty"`
@@ -161,6 +159,14 @@ type HeaderMatch struct { // TODO: zhaohuabing this type could be replaced with
// +optional
// +kubebuilder:validation:MaxLength=1024
Value *string `json:"value,omitempty"`
+
+ // Invert specifies whether the value match result will be inverted.
+ // Do not set this field when Type="Distinct", implying matching on any/all unique
+ // values within the header.
+ //
+ // +optional
+ // +kubebuilder:default=false
+ Invert *bool `json:"invert,omitempty"`
}
// HeaderMatchType specifies the semantics of how HTTP header values should be compared.
diff --git a/api/v1alpha1/securitypolicy_types.go b/api/v1alpha1/securitypolicy_types.go
index 1720d0561a5..542971ec1d6 100644
--- a/api/v1alpha1/securitypolicy_types.go
+++ b/api/v1alpha1/securitypolicy_types.go
@@ -41,6 +41,7 @@ type SecurityPolicy struct {
// +kubebuilder:validation:XValidation:rule="has(self.targetRefs) ? self.targetRefs.all(ref, ref.group == 'gateway.networking.k8s.io') : true ", message="this policy can only have a targetRefs[*].group of gateway.networking.k8s.io"
// +kubebuilder:validation:XValidation:rule="has(self.targetRefs) ? self.targetRefs.all(ref, ref.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute']) : true ", message="this policy can only have a targetRefs[*].kind of Gateway/HTTPRoute/GRPCRoute"
// +kubebuilder:validation:XValidation:rule="has(self.targetRefs) ? self.targetRefs.all(ref, !has(ref.sectionName)) : true",message="this policy does not yet support the sectionName field"
+// +kubebuilder:validation:XValidation:rule="(has(self.authorization) && has(self.authorization.rules) && self.authorization.rules.exists(r, has(r.principal.jwt))) ? has(self.jwt) : true", message="if authorization.rules.principal.jwt is used, jwt must be defined"
//
// SecurityPolicySpec defines the desired state of SecurityPolicy.
type SecurityPolicySpec struct {
diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go
index 6ad310859bc..036054dc47e 100644
--- a/api/v1alpha1/shared_types.go
+++ b/api/v1alpha1/shared_types.go
@@ -10,6 +10,7 @@ import (
autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+ "k8s.io/apimachinery/pkg/api/resource"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)
@@ -21,15 +22,15 @@ const (
// DefaultDeploymentMemoryResourceRequests for deployment memory resource
DefaultDeploymentMemoryResourceRequests = "512Mi"
// DefaultEnvoyProxyImage is the default image used by envoyproxy
- DefaultEnvoyProxyImage = "envoyproxy/envoy:distroless-dev"
+ DefaultEnvoyProxyImage = "docker.io/envoyproxy/envoy:distroless-dev"
// DefaultShutdownManagerCPUResourceRequests for shutdown manager cpu resource
DefaultShutdownManagerCPUResourceRequests = "10m"
// DefaultShutdownManagerMemoryResourceRequests for shutdown manager memory resource
DefaultShutdownManagerMemoryResourceRequests = "32Mi"
// DefaultShutdownManagerImage is the default image used for the shutdown manager.
- DefaultShutdownManagerImage = "envoyproxy/gateway-dev:latest"
+ DefaultShutdownManagerImage = "docker.io/envoyproxy/gateway-dev:latest"
// DefaultRateLimitImage is the default image used by ratelimit.
- DefaultRateLimitImage = "envoyproxy/ratelimit:master"
+ DefaultRateLimitImage = "docker.io/envoyproxy/ratelimit:master"
// HTTPProtocol is the common-used http protocol.
HTTPProtocol = "http"
// GRPCProtocol is the common-used grpc protocol.
@@ -46,16 +47,15 @@ type GroupVersionKind struct {
// ProviderType defines the types of providers supported by Envoy Gateway.
//
-// +kubebuilder:validation:Enum=Kubernetes
+// +kubebuilder:validation:Enum=Kubernetes;Custom
type ProviderType string
const (
// ProviderTypeKubernetes defines the "Kubernetes" provider.
ProviderTypeKubernetes ProviderType = "Kubernetes"
- // ProviderTypeFile defines the "File" provider. This type is not implemented
- // until https://github.com/envoyproxy/gateway/issues/1001 is fixed.
- ProviderTypeFile ProviderType = "File"
+ // ProviderTypeCustom defines the "Custom" provider.
+ ProviderTypeCustom ProviderType = "Custom"
)
// KubernetesDeploymentSpec defines the desired state of the Kubernetes deployment resource.
@@ -98,7 +98,7 @@ type KubernetesDeploymentSpec struct {
// TODO: Expose config as use cases are better understood, e.g. labels.
}
-// KubernetesDaemonsetSpec defines the desired state of the Kubernetes daemonset resource.
+// KubernetesDaemonSetSpec defines the desired state of the Kubernetes daemonset resource.
type KubernetesDaemonSetSpec struct {
// Patch defines how to perform the patch operation to daemonset
//
@@ -262,6 +262,12 @@ type KubernetesServiceSpec struct {
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
+ // Labels that should be appended to the service.
+ // By default, no labels are appended.
+ //
+ // +optional
+ Labels map[string]string `json:"labels,omitempty"`
+
// Type determines how the Service is exposed. Defaults to LoadBalancer.
// Valid options are ClusterIP, LoadBalancer and NodePort.
// "LoadBalancer" means a service will be exposed via an external load balancer (if the cloud provider supports it).
@@ -400,6 +406,11 @@ type KubernetesPodDisruptionBudgetSpec struct {
// and resilience during maintenance operations.
// +optional
MinAvailable *int32 `json:"minAvailable,omitempty"`
+
+ // Patch defines how to perform the patch operation to the PodDisruptionBudget
+ //
+ // +optional
+ Patch *KubernetesPatchSpec `json:"patch,omitempty"`
}
// KubernetesHorizontalPodAutoscalerSpec defines Kubernetes Horizontal Pod Autoscaler settings of Envoy Proxy Deployment.
@@ -437,6 +448,11 @@ type KubernetesHorizontalPodAutoscalerSpec struct {
//
// +optional
Behavior *autoscalingv2.HorizontalPodAutoscalerBehavior `json:"behavior,omitempty"`
+
+ // Patch defines how to perform the patch operation to the HorizontalPodAutoscaler
+ //
+ // +optional
+ Patch *KubernetesPatchSpec `json:"patch,omitempty"`
}
// HTTPStatus defines the http status code.
@@ -455,7 +471,9 @@ const (
JSONMerge MergeType = "JSONMerge"
)
-// KubernetesPatchSpec defines how to perform the patch operation
+// KubernetesPatchSpec defines how to perform the patch operation.
+// Note that `value` can be an in-line YAML document, as can be seen in e.g. (the example of patching the Envoy proxy Deployment)[https://gateway.envoyproxy.io/docs/tasks/operations/customize-envoyproxy/#patching-deployment-for-envoyproxy].
+// Note also that, currently, strings containing literal JSON are _rejected_.
type KubernetesPatchSpec struct {
// Type is the type of merge operation to perform
//
@@ -472,9 +490,250 @@ type BackendRef struct {
// BackendObjectReference references a Kubernetes object that represents the backend.
// Only Service kind is supported for now.
gwapiv1.BackendObjectReference `json:",inline"`
+ // Fallback indicates whether the backend is designated as a fallback.
+ // Multiple fallback backends can be configured.
+ // It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ // when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ // The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ // the health of the active backends falls below 72%.
+ //
+ // +optional
+ Fallback *bool `json:"fallback,omitempty"`
+}
+
+// BackendCluster contains all the configuration required for configuring access
+// to a backend. This can include multiple endpoints, and settings that apply for
+// managing the connection to all these endpoints.
+type BackendCluster struct {
+ // BackendRef references a Kubernetes object that represents the
+ // backend server to which the authorization request will be sent.
+ //
+ // Deprecated: Use BackendRefs instead.
+ // +optional
+ BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"`
+
+ // BackendRefs references a Kubernetes object that represents the
+ // backend server to which the authorization request will be sent.
+ //
+ // +kubebuilder:validation:MaxItems=16
+ // +optional
+ BackendRefs []BackendRef `json:"backendRefs,omitempty"`
+
+ // BackendSettings holds configuration for managing the connection
+ // to the backend.
+ //
+ // +optional
+ BackendSettings *ClusterSettings `json:"backendSettings,omitempty"`
+}
+
+// ClusterSettings provides the various knobs that can be set to control how traffic to a given
+// backend will be configured.
+type ClusterSettings struct {
+ // LoadBalancer policy to apply when routing traffic from the gateway to
+ // the backend endpoints. Defaults to `LeastRequest`.
+ // +optional
+ LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty"`
+
+ // Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
+ // If not set, retry will be disabled.
+ // +optional
+ Retry *Retry `json:"retry,omitempty"`
+
+ // ProxyProtocol enables the Proxy Protocol when communicating with the backend.
+ // +optional
+ ProxyProtocol *ProxyProtocol `json:"proxyProtocol,omitempty"`
+
+ // TcpKeepalive settings associated with the upstream client connection.
+ // Disabled by default.
+ //
+ // +optional
+ TCPKeepalive *TCPKeepalive `json:"tcpKeepalive,omitempty"`
+
+ // HealthCheck allows gateway to perform active health checking on backends.
+ //
+ // +optional
+ HealthCheck *HealthCheck `json:"healthCheck,omitempty"`
+
+ // Circuit Breaker settings for the upstream connections and requests.
+ // If not set, circuit breakers will be enabled with the default thresholds
+ //
+ // +optional
+ CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty"`
+
+ // Timeout settings for the backend connections.
+ //
+ // +optional
+ Timeout *Timeout `json:"timeout,omitempty"`
+
+ // Connection includes backend connection settings.
+ //
+ // +optional
+ Connection *BackendConnection `json:"connection,omitempty"`
+
+ // DNS includes dns resolution settings.
+ //
+ // +optional
+ DNS *DNS `json:"dns,omitempty"`
+
+ // HTTP2 provides HTTP/2 configuration for backend connections.
+ //
+ // +optional
+ HTTP2 *HTTP2Settings `json:"http2,omitempty"`
}
// CIDR defines a CIDR Address range.
// A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address range such as "2001:0db8:11a3:09d7::/64".
// +kubebuilder:validation:Pattern=`((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]+))|((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/([0-9]+))`
type CIDR string
+
+type InvalidMessageAction string
+
+const (
+ InvalidMessageActionTerminateConnection InvalidMessageAction = "TerminateConnection"
+ InvalidMessageActionTerminateStream InvalidMessageAction = "TerminateStream"
+)
+
+// HTTP2Settings provides HTTP/2 configuration for listeners and backends.
+type HTTP2Settings struct {
+ // InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ // If not set, the default value is 64 KiB(64*1024).
+ //
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
+ // +optional
+ InitialStreamWindowSize *resource.Quantity `json:"initialStreamWindowSize,omitempty"`
+
+ // InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ // If not set, the default value is 1 MiB.
+ //
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
+ // +optional
+ InitialConnectionWindowSize *resource.Quantity `json:"initialConnectionWindowSize,omitempty"`
+
+ // MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ // If not set, the default value is 100.
+ // +kubebuilder:validation:Minimum=1
+ // +kubebuilder:validation:Maximum=2147483647
+ // +optional
+ MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty"`
+
+ // OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ // It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ // https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ // Default: TerminateConnection
+ // +optional
+ OnInvalidMessage *InvalidMessageAction `json:"onInvalidMessage,omitempty"`
+}
+
+// ResponseOverride defines the configuration to override specific responses with a custom one.
+type ResponseOverride struct {
+ // Match configuration.
+ Match CustomResponseMatch `json:"match"`
+ // Response configuration.
+ Response CustomResponse `json:"response"`
+}
+
+// CustomResponseMatch defines the configuration for matching a user response to return a custom one.
+type CustomResponseMatch struct {
+ // Status code to match on. The match evaluates to true if any of the matches are successful.
+ // +kubebuilder:validation:MinItems=1
+ // +kubebuilder:validation:MaxItems=50
+ StatusCodes []StatusCodeMatch `json:"statusCodes"`
+}
+
+// StatusCodeValueType defines the types of values for the status code match supported by Envoy Gateway.
+// +kubebuilder:validation:Enum=Value;Range
+type StatusCodeValueType string
+
+const (
+ // StatusCodeValueTypeValue defines the "Value" status code match type.
+ StatusCodeValueTypeValue StatusCodeValueType = "Value"
+
+ // StatusCodeValueTypeRange defines the "Range" status code match type.
+ StatusCodeValueTypeRange StatusCodeValueType = "Range"
+)
+
+// StatusCodeMatch defines the configuration for matching a status code.
+// +kubebuilder:validation:XValidation:message="value must be set for type Value",rule="(!has(self.type) || self.type == 'Value')? has(self.value) : true"
+// +kubebuilder:validation:XValidation:message="range must be set for type Range",rule="(has(self.type) && self.type == 'Range')? has(self.range) : true"
+type StatusCodeMatch struct {
+ // Type is the type of value.
+ // Valid values are Value and Range, default is Value.
+ //
+ // +kubebuilder:default=Value
+ // +kubebuilder:validation:Enum=Value;Range
+ // +unionDiscriminator
+ Type *StatusCodeValueType `json:"type"`
+
+ // Value contains the value of the status code.
+ //
+ // +optional
+ Value *int `json:"value,omitempty"`
+
+ // Range contains the range of status codes.
+ //
+ // +optional
+ Range *StatusCodeRange `json:"range,omitempty"`
+}
+
+// StatusCodeRange defines the configuration for define a range of status codes.
+// +kubebuilder:validation:XValidation: message="end must be greater than start",rule="self.end > self.start"
+type StatusCodeRange struct {
+ // Start of the range, including the start value.
+ Start int `json:"start"`
+ // End of the range, including the end value.
+ End int `json:"end"`
+}
+
+// CustomResponse defines the configuration for returning a custom response.
+type CustomResponse struct {
+ // Content Type of the response. This will be set in the Content-Type header.
+ //
+ // +optional
+ ContentType *string `json:"contentType,omitempty"`
+
+ // Body of the Custom Response
+ Body CustomResponseBody `json:"body"`
+}
+
+// ResponseValueType defines the types of values for the response body supported by Envoy Gateway.
+// +kubebuilder:validation:Enum=Inline;ValueRef
+type ResponseValueType string
+
+const (
+ // ResponseValueTypeInline defines the "Inline" response body type.
+ ResponseValueTypeInline ResponseValueType = "Inline"
+
+ // ResponseValueTypeValueRef defines the "ValueRef" response body type.
+ ResponseValueTypeValueRef ResponseValueType = "ValueRef"
+)
+
+// CustomResponseBody
+// +kubebuilder:validation:XValidation:message="inline must be set for type Inline",rule="(!has(self.type) || self.type == 'Inline')? has(self.inline) : true"
+// +kubebuilder:validation:XValidation:message="valueRef must be set for type ValueRef",rule="(has(self.type) && self.type == 'ValueRef')? has(self.valueRef) : true"
+// +kubebuilder:validation:XValidation:message="only ConfigMap is supported for ValueRef",rule="has(self.valueRef) ? self.valueRef.kind == 'ConfigMap' : true"
+type CustomResponseBody struct {
+ // Type is the type of method to use to read the body value.
+ // Valid values are Inline and ValueRef, default is Inline.
+ //
+ // +kubebuilder:default=Inline
+ // +kubebuilder:validation:Enum=Inline;ValueRef
+ // +unionDiscriminator
+ Type *ResponseValueType `json:"type"`
+
+ // Inline contains the value as an inline string.
+ //
+ // +optional
+ Inline *string `json:"inline,omitempty"`
+
+ // ValueRef contains the contents of the body
+ // specified as a local object reference.
+ // Only a reference to ConfigMap is supported.
+ //
+ // The value of key `response.body` in the ConfigMap will be used as the response body.
+ // If the key is not found, the first value in the ConfigMap will be used.
+ //
+ // +optional
+ ValueRef *gwapiv1.LocalObjectReference `json:"valueRef,omitempty"`
+}
diff --git a/api/v1alpha1/timeout_types.go b/api/v1alpha1/timeout_types.go
index 36c0c320ed2..008582578d1 100644
--- a/api/v1alpha1/timeout_types.go
+++ b/api/v1alpha1/timeout_types.go
@@ -40,6 +40,11 @@ type HTTPTimeout struct {
//
// +optional
MaxConnectionDuration *gwapiv1.Duration `json:"maxConnectionDuration,omitempty"`
+
+ // RequestTimeout is the time until which entire response is received from the upstream.
+ //
+ // +optional
+ RequestTimeout *gwapiv1.Duration `json:"requestTimeout,omitempty" yaml:"requestTimeout,omitempty"`
}
type ClientTimeout struct {
diff --git a/api/v1alpha1/tls_types.go b/api/v1alpha1/tls_types.go
index 38c52761125..bf2a1f50569 100644
--- a/api/v1alpha1/tls_types.go
+++ b/api/v1alpha1/tls_types.go
@@ -15,6 +15,10 @@ type ClientTLSSettings struct {
// +optional
ClientValidation *ClientValidationContext `json:"clientValidation,omitempty"`
TLSSettings `json:",inline"`
+
+ // Session defines settings related to TLS session management.
+ // +optional
+ Session *Session `json:"session,omitempty"`
}
// +kubebuilder:validation:XValidation:rule="has(self.minVersion) && self.minVersion == '1.3' ? !has(self.ciphers) : true", message="setting ciphers has no effect if the minimum possible TLS version is 1.3"
@@ -65,7 +69,12 @@ type TLSSettings struct {
SignatureAlgorithms []string `json:"signatureAlgorithms,omitempty"`
// ALPNProtocols supplies the list of ALPN protocols that should be
- // exposed by the listener. By default h2 and http/1.1 are enabled.
+ // exposed by the listener or used by the proxy to connect to the backend.
+ // Defaults:
+ // 1. HTTPS Routes: h2 and http/1.1 are enabled in listener context.
+ // 2. Other Routes: ALPN is disabled.
+ // 3. Backends: proxy uses the appropriate ALPN options for the backend protocol.
+ // When an empty list is provided, the ALPN TLS extension is disabled.
// Supported values are:
// - http/1.0
// - http/1.1
@@ -133,3 +142,40 @@ type ClientValidationContext struct {
// +optional
CACertificateRefs []gwapiv1.SecretObjectReference `json:"caCertificateRefs,omitempty"`
}
+
+// Session defines settings related to TLS session management.
+type Session struct {
+ // Resumption determines the proxy's supported TLS session resumption option.
+ // By default, Envoy Gateway does not enable session resumption. Use sessionResumption to
+ // enable stateful and stateless session resumption. Users should consider security impacts
+ // of different resumption methods. Performance gains from resumption are diminished when
+ // Envoy proxy is deployed with more than one replica.
+ // +optional
+ Resumption *SessionResumption `json:"resumption,omitempty"`
+}
+
+// SessionResumption defines supported tls session resumption methods and their associated configuration.
+type SessionResumption struct {
+ // Stateless defines setting for stateless (session-ticket based) session resumption
+ // +optional
+ Stateless *StatelessTLSSessionResumption `json:"stateless,omitempty"`
+
+ // Stateful defines setting for stateful (session-id based) session resumption
+ // +optional
+ Stateful *StatefulTLSSessionResumption `json:"stateful,omitempty"`
+}
+
+// StatefulTLSSessionResumption defines the stateful (session-id based) type of TLS session resumption.
+// Note: When Envoy Proxy is deployed with more than one replica, session caches are not synchronized
+// between instances, possibly leading to resumption failures.
+// Envoy does not re-validate client certificates upon session resumption.
+// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-routematch-tlscontextmatchoptions
+type StatefulTLSSessionResumption struct{}
+
+// StatelessTLSSessionResumption defines the stateless (session-ticket based) type of TLS session resumption.
+// Note: When Envoy Proxy is deployed with more than one replica, session ticket encryption keys are not
+// synchronized between instances, possibly leading to resumption failures.
+// In-memory session ticket encryption keys are rotated every 48 hours.
+// https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#extensions-transport-sockets-tls-v3-tlssessionticketkeys
+// https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#Session-tickets
+type StatelessTLSSessionResumption struct{}
diff --git a/api/v1alpha1/tracing_types.go b/api/v1alpha1/tracing_types.go
index b7be478de15..293664cddba 100644
--- a/api/v1alpha1/tracing_types.go
+++ b/api/v1alpha1/tracing_types.go
@@ -26,14 +26,19 @@ type TracingProviderType string
const (
TracingProviderTypeOpenTelemetry TracingProviderType = "OpenTelemetry"
TracingProviderTypeZipkin TracingProviderType = "Zipkin"
+ TracingProviderTypeDatadog TracingProviderType = "Datadog"
)
// TracingProvider defines the tracing provider configuration.
//
// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true"
type TracingProvider struct {
+ BackendCluster `json:",inline"`
// Type defines the tracing provider type.
- // +kubebuilder:validation:Enum=OpenTelemetry;Zipkin
+ // +kubebuilder:validation:Enum=OpenTelemetry;Zipkin;Datadog
// +kubebuilder:default=OpenTelemetry
Type TracingProviderType `json:"type"`
// Host define the provider service hostname.
@@ -48,15 +53,6 @@ type TracingProvider struct {
// +kubebuilder:validation:Minimum=0
// +kubebuilder:default=4317
Port int32 `json:"port,omitempty"`
- // BackendRefs references a Kubernetes object that represents the
- // backend server to which the trace will be sent.
- // Only Service kind is supported for now.
- //
- // +optional
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs,omitempty"`
// Zipkin defines the Zipkin tracing provider configuration
// +optional
Zipkin *ZipkinTracingProvider `json:"zipkin,omitempty"`
diff --git a/api/v1alpha1/validation/envoygateway_validate.go b/api/v1alpha1/validation/envoygateway_validate.go
index 91d61bcc80d..d27e2e1e416 100644
--- a/api/v1alpha1/validation/envoygateway_validate.go
+++ b/api/v1alpha1/validation/envoygateway_validate.go
@@ -6,115 +6,224 @@
package validation
import (
- "errors"
"fmt"
"net/url"
- gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
-
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
)
// ValidateEnvoyGateway validates the provided EnvoyGateway.
func ValidateEnvoyGateway(eg *egv1a1.EnvoyGateway) error {
- switch {
- case eg == nil:
- return errors.New("envoy gateway config is unspecified")
- case eg.Gateway == nil:
- return errors.New("gateway is unspecified")
- case len(eg.Gateway.ControllerName) == 0:
- return errors.New("gateway controllerName is unspecified")
- case eg.Provider == nil:
- return errors.New("provider is unspecified")
- case eg.Provider.Type != egv1a1.ProviderTypeKubernetes:
- return fmt.Errorf("unsupported provider %v", eg.Provider.Type)
- case eg.Provider.Kubernetes != nil && eg.Provider.Kubernetes.Watch != nil:
- watch := eg.Provider.Kubernetes.Watch
- switch watch.Type {
- case egv1a1.KubernetesWatchModeTypeNamespaces:
- if len(watch.Namespaces) == 0 {
- return errors.New("namespaces should be specified when envoy gateway watch mode is 'Namespaces'")
- }
- case egv1a1.KubernetesWatchModeTypeNamespaceSelector:
- if watch.NamespaceSelector == nil {
- return errors.New("namespaceSelector should be specified when envoy gateway watch mode is 'NamespaceSelector'")
- }
- default:
- return errors.New("envoy gateway watch mode invalid, should be 'Namespaces' or 'NamespaceSelector'")
+ if eg == nil {
+ return fmt.Errorf("envoy gateway config is unspecified")
+ }
+
+ if eg.Gateway == nil {
+ return fmt.Errorf("gateway is unspecified")
+ }
+
+ if len(eg.Gateway.ControllerName) == 0 {
+ return fmt.Errorf("gateway controllerName is unspecified")
+ }
+
+ if eg.Provider == nil {
+ return fmt.Errorf("provider is unspecified")
+ }
+
+ switch eg.Provider.Type {
+ case egv1a1.ProviderTypeKubernetes:
+ if err := validateEnvoyGatewayKubernetesProvider(eg.Provider.Kubernetes); err != nil {
+ return err
}
- case eg.Logging != nil && len(eg.Logging.Level) != 0:
- level := eg.Logging.Level
- for component, logLevel := range level {
- switch component {
- case egv1a1.LogComponentGatewayDefault,
- egv1a1.LogComponentProviderRunner,
- egv1a1.LogComponentGatewayAPIRunner,
- egv1a1.LogComponentXdsTranslatorRunner,
- egv1a1.LogComponentXdsServerRunner,
- egv1a1.LogComponentInfrastructureRunner,
- egv1a1.LogComponentGlobalRateLimitRunner:
- switch logLevel {
- case egv1a1.LogLevelDebug, egv1a1.LogLevelError, egv1a1.LogLevelWarn, egv1a1.LogLevelInfo:
- default:
- return errors.New("envoy gateway logging level invalid. valid options: info/debug/warn/error")
- }
- default:
- return errors.New("envoy gateway logging components invalid. valid options: system/provider/gateway-api/xds-translator/xds-server/infrastructure")
- }
+ case egv1a1.ProviderTypeCustom:
+ if err := validateEnvoyGatewayCustomProvider(eg.Provider.Custom); err != nil {
+ return err
}
- case eg.RateLimit != nil:
- if eg.RateLimit.Backend.Type != egv1a1.RedisBackendType {
- return fmt.Errorf("unsupported ratelimit backend %v", eg.RateLimit.Backend.Type)
+ default:
+ return fmt.Errorf("unsupported provider type")
+ }
+
+ if err := validateEnvoyGatewayLogging(eg.Logging); err != nil {
+ return err
+ }
+
+ if err := validateEnvoyGatewayRateLimit(eg.RateLimit); err != nil {
+ return err
+ }
+
+ if err := validateEnvoyGatewayExtensionManager(eg.ExtensionManager); err != nil {
+ return err
+ }
+
+ if err := validateEnvoyGatewayTelemetry(eg.Telemetry); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func validateEnvoyGatewayKubernetesProvider(provider *egv1a1.EnvoyGatewayKubernetesProvider) error {
+ if provider == nil || provider.Watch == nil {
+ return nil
+ }
+
+ watch := provider.Watch
+ switch watch.Type {
+ case egv1a1.KubernetesWatchModeTypeNamespaces:
+ if len(watch.Namespaces) == 0 {
+ return fmt.Errorf("namespaces should be specified when envoy gateway watch mode is 'Namespaces'")
}
- if eg.RateLimit.Backend.Redis == nil || eg.RateLimit.Backend.Redis.URL == "" {
- return fmt.Errorf("empty ratelimit redis settings")
+ case egv1a1.KubernetesWatchModeTypeNamespaceSelector:
+ if watch.NamespaceSelector == nil {
+ return fmt.Errorf("namespaceSelector should be specified when envoy gateway watch mode is 'NamespaceSelector'")
}
- if _, err := url.Parse(eg.RateLimit.Backend.Redis.URL); err != nil {
- return fmt.Errorf("unknown ratelimit redis url format: %w", err)
+ default:
+ return fmt.Errorf("envoy gateway watch mode invalid, should be 'Namespaces' or 'NamespaceSelector'")
+ }
+ return nil
+}
+
+func validateEnvoyGatewayCustomProvider(provider *egv1a1.EnvoyGatewayCustomProvider) error {
+ if provider == nil {
+ return fmt.Errorf("empty custom provider settings")
+ }
+
+ if err := validateEnvoyGatewayCustomResourceProvider(provider.Resource); err != nil {
+ return err
+ }
+
+ if err := validateEnvoyGatewayCustomInfrastructureProvider(provider.Infrastructure); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func validateEnvoyGatewayCustomResourceProvider(resource egv1a1.EnvoyGatewayResourceProvider) error {
+ switch resource.Type {
+ case egv1a1.ResourceProviderTypeFile:
+ if resource.File == nil {
+ return fmt.Errorf("field 'file' should be specified when resource type is 'File'")
}
- case eg.ExtensionManager != nil:
- if eg.ExtensionManager.Hooks == nil || eg.ExtensionManager.Hooks.XDSTranslator == nil {
- return fmt.Errorf("registered extension has no hooks specified")
+
+ if len(resource.File.Paths) == 0 {
+ return fmt.Errorf("no paths were assigned for file resource provider to watch")
}
+ default:
+ return fmt.Errorf("unsupported resource provider: %s", resource.Type)
+ }
+ return nil
+}
- if len(eg.ExtensionManager.Hooks.XDSTranslator.Pre) == 0 && len(eg.ExtensionManager.Hooks.XDSTranslator.Post) == 0 {
- return fmt.Errorf("registered extension has no hooks specified")
+func validateEnvoyGatewayCustomInfrastructureProvider(infra *egv1a1.EnvoyGatewayInfrastructureProvider) error {
+ if infra == nil {
+ return nil
+ }
+
+ switch infra.Type {
+ case egv1a1.InfrastructureProviderTypeHost:
+ if infra.Host == nil {
+ return fmt.Errorf("field 'host' should be specified when infrastructure type is 'Host'")
}
+ default:
+ return fmt.Errorf("unsupported infrastructure provdier: %s", infra.Type)
+ }
+ return nil
+}
+
+func validateEnvoyGatewayLogging(logging *egv1a1.EnvoyGatewayLogging) error {
+ if logging == nil || len(logging.Level) == 0 {
+ return nil
+ }
- if eg.ExtensionManager.Service == nil {
- return fmt.Errorf("extension service config is empty")
+ for component, logLevel := range logging.Level {
+ switch component {
+ case egv1a1.LogComponentGatewayDefault,
+ egv1a1.LogComponentProviderRunner,
+ egv1a1.LogComponentGatewayAPIRunner,
+ egv1a1.LogComponentXdsTranslatorRunner,
+ egv1a1.LogComponentXdsServerRunner,
+ egv1a1.LogComponentInfrastructureRunner,
+ egv1a1.LogComponentGlobalRateLimitRunner:
+ switch logLevel {
+ case egv1a1.LogLevelDebug, egv1a1.LogLevelError, egv1a1.LogLevelWarn, egv1a1.LogLevelInfo:
+ default:
+ return fmt.Errorf("envoy gateway logging level invalid. valid options: info/debug/warn/error")
+ }
+ default:
+ return fmt.Errorf("envoy gateway logging components invalid. valid options: system/provider/gateway-api/xds-translator/xds-server/infrastructure")
}
+ }
+ return nil
+}
- switch {
- case eg.ExtensionManager.Service.Host == "" && eg.ExtensionManager.Service.FQDN == nil && eg.ExtensionManager.Service.Unix == nil && eg.ExtensionManager.Service.IP == nil:
- return fmt.Errorf("extension service must contain a configured target")
+func validateEnvoyGatewayRateLimit(rateLimit *egv1a1.RateLimit) error {
+ if rateLimit == nil {
+ return nil
+ }
+ if rateLimit.Backend.Type != egv1a1.RedisBackendType {
+ return fmt.Errorf("unsupported ratelimit backend %v", rateLimit.Backend.Type)
+ }
+ if rateLimit.Backend.Redis == nil || rateLimit.Backend.Redis.URL == "" {
+ return fmt.Errorf("empty ratelimit redis settings")
+ }
+ if _, err := url.Parse(rateLimit.Backend.Redis.URL); err != nil {
+ return fmt.Errorf("unknown ratelimit redis url format: %w", err)
+ }
+ return nil
+}
- case eg.ExtensionManager.Service.FQDN != nil && (eg.ExtensionManager.Service.IP != nil || eg.ExtensionManager.Service.Unix != nil || eg.ExtensionManager.Service.Host != ""),
- eg.ExtensionManager.Service.IP != nil && (eg.ExtensionManager.Service.FQDN != nil || eg.ExtensionManager.Service.Unix != nil || eg.ExtensionManager.Service.Host != ""),
- eg.ExtensionManager.Service.Unix != nil && (eg.ExtensionManager.Service.IP != nil || eg.ExtensionManager.Service.FQDN != nil || eg.ExtensionManager.Service.Host != ""):
+func validateEnvoyGatewayExtensionManager(extensionManager *egv1a1.ExtensionManager) error {
+ if extensionManager == nil {
+ return nil
+ }
- return fmt.Errorf("only one backend target can be configured for the extension manager")
+ if extensionManager.Hooks == nil || extensionManager.Hooks.XDSTranslator == nil {
+ return fmt.Errorf("registered extension has no hooks specified")
+ }
- }
+ if len(extensionManager.Hooks.XDSTranslator.Pre) == 0 && len(extensionManager.Hooks.XDSTranslator.Post) == 0 {
+ return fmt.Errorf("registered extension has no hooks specified")
+ }
- if eg.ExtensionManager.Service.TLS != nil {
- certificateRefKind := eg.ExtensionManager.Service.TLS.CertificateRef.Kind
+ if extensionManager.Service == nil {
+ return fmt.Errorf("extension service config is empty")
+ }
- if certificateRefKind == nil {
- return fmt.Errorf("certificateRef empty in extension service server TLS settings")
- }
+ switch {
+ case extensionManager.Service.Host == "" && extensionManager.Service.FQDN == nil && extensionManager.Service.Unix == nil && extensionManager.Service.IP == nil:
+ return fmt.Errorf("extension service must contain a configured target")
- if *certificateRefKind != gwapiv1.Kind("Secret") {
- return fmt.Errorf("unsupported extension server TLS certificateRef %v", certificateRefKind)
- }
+ case extensionManager.Service.FQDN != nil && (extensionManager.Service.IP != nil || extensionManager.Service.Unix != nil || extensionManager.Service.Host != ""),
+ extensionManager.Service.IP != nil && (extensionManager.Service.FQDN != nil || extensionManager.Service.Unix != nil || extensionManager.Service.Host != ""),
+ extensionManager.Service.Unix != nil && (extensionManager.Service.IP != nil || extensionManager.Service.FQDN != nil || extensionManager.Service.Host != ""):
+ return fmt.Errorf("only one backend target can be configured for the extension manager")
+ }
+
+ if extensionManager.Service.TLS != nil {
+ certificateRefKind := extensionManager.Service.TLS.CertificateRef.Kind
+
+ if certificateRefKind == nil {
+ return fmt.Errorf("certificateRef empty in extension service server TLS settings")
}
- case eg.Telemetry != nil:
- if eg.Telemetry.Metrics != nil {
- for _, sink := range eg.Telemetry.Metrics.Sinks {
- if sink.Type == egv1a1.MetricSinkTypeOpenTelemetry {
- if sink.OpenTelemetry == nil {
- return fmt.Errorf("OpenTelemetry is required when sink Type is OpenTelemetry")
- }
+
+ if *certificateRefKind != "Secret" {
+ return fmt.Errorf("unsupported extension server TLS certificateRef %v", certificateRefKind)
+ }
+ }
+ return nil
+}
+
+func validateEnvoyGatewayTelemetry(telemetry *egv1a1.EnvoyGatewayTelemetry) error {
+ if telemetry == nil {
+ return nil
+ }
+
+ if telemetry.Metrics != nil {
+ for _, sink := range telemetry.Metrics.Sinks {
+ if sink.Type == egv1a1.MetricSinkTypeOpenTelemetry {
+ if sink.OpenTelemetry == nil {
+ return fmt.Errorf("OpenTelemetry is required when sink Type is OpenTelemetry")
}
}
}
diff --git a/api/v1alpha1/validation/envoygateway_validate_test.go b/api/v1alpha1/validation/envoygateway_validate_test.go
index 004a5ac8298..a0cbc7b059e 100644
--- a/api/v1alpha1/validation/envoygateway_validate_test.go
+++ b/api/v1alpha1/validation/envoygateway_validate_test.go
@@ -68,11 +68,173 @@ func TestValidateEnvoyGateway(t *testing.T) {
expect: false,
},
{
- name: "unsupported provider",
+ name: "nil custom provider",
eg: &egv1a1.EnvoyGateway{
EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
- Gateway: egv1a1.DefaultGateway(),
- Provider: &egv1a1.EnvoyGatewayProvider{Type: egv1a1.ProviderTypeFile},
+ Gateway: egv1a1.DefaultGateway(),
+ Provider: &egv1a1.EnvoyGatewayProvider{
+ Type: egv1a1.ProviderTypeCustom,
+ Custom: nil,
+ },
+ },
+ },
+ expect: false,
+ },
+ {
+ name: "empty custom provider",
+ eg: &egv1a1.EnvoyGateway{
+ EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
+ Gateway: egv1a1.DefaultGateway(),
+ Provider: &egv1a1.EnvoyGatewayProvider{
+ Type: egv1a1.ProviderTypeCustom,
+ Custom: &egv1a1.EnvoyGatewayCustomProvider{},
+ },
+ },
+ },
+ expect: false,
+ },
+ {
+ name: "custom provider with file resource provider and host infra provider",
+ eg: &egv1a1.EnvoyGateway{
+ EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
+ Gateway: egv1a1.DefaultGateway(),
+ Provider: &egv1a1.EnvoyGatewayProvider{
+ Type: egv1a1.ProviderTypeCustom,
+ Custom: &egv1a1.EnvoyGatewayCustomProvider{
+ Resource: egv1a1.EnvoyGatewayResourceProvider{
+ Type: egv1a1.ResourceProviderTypeFile,
+ File: &egv1a1.EnvoyGatewayFileResourceProvider{
+ Paths: []string{"foo", "bar"},
+ },
+ },
+ Infrastructure: &egv1a1.EnvoyGatewayInfrastructureProvider{
+ Type: egv1a1.InfrastructureProviderTypeHost,
+ Host: &egv1a1.EnvoyGatewayHostInfrastructureProvider{},
+ },
+ },
+ },
+ },
+ },
+ expect: true,
+ },
+ {
+ name: "custom provider with file provider and k8s infra provider",
+ eg: &egv1a1.EnvoyGateway{
+ EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
+ Gateway: egv1a1.DefaultGateway(),
+ Provider: &egv1a1.EnvoyGatewayProvider{
+ Type: egv1a1.ProviderTypeCustom,
+ Custom: &egv1a1.EnvoyGatewayCustomProvider{
+ Resource: egv1a1.EnvoyGatewayResourceProvider{
+ Type: egv1a1.ResourceProviderTypeFile,
+ File: &egv1a1.EnvoyGatewayFileResourceProvider{
+ Paths: []string{"foo", "bar"},
+ },
+ },
+ },
+ },
+ },
+ },
+ expect: true,
+ },
+ {
+ name: "custom provider with unsupported resource provider",
+ eg: &egv1a1.EnvoyGateway{
+ EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
+ Gateway: egv1a1.DefaultGateway(),
+ Provider: &egv1a1.EnvoyGatewayProvider{
+ Type: egv1a1.ProviderTypeCustom,
+ Custom: &egv1a1.EnvoyGatewayCustomProvider{
+ Resource: egv1a1.EnvoyGatewayResourceProvider{
+ Type: "foobar",
+ },
+ },
+ },
+ },
+ },
+ expect: false,
+ },
+ {
+ name: "custom provider with file provider but no file struct",
+ eg: &egv1a1.EnvoyGateway{
+ EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
+ Gateway: egv1a1.DefaultGateway(),
+ Provider: &egv1a1.EnvoyGatewayProvider{
+ Type: egv1a1.ProviderTypeCustom,
+ Custom: &egv1a1.EnvoyGatewayCustomProvider{
+ Resource: egv1a1.EnvoyGatewayResourceProvider{
+ Type: egv1a1.ResourceProviderTypeFile,
+ },
+ },
+ },
+ },
+ },
+ expect: false,
+ },
+ {
+ name: "custom provider with file provider and host infra provider but no host struct",
+ eg: &egv1a1.EnvoyGateway{
+ EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
+ Gateway: egv1a1.DefaultGateway(),
+ Provider: &egv1a1.EnvoyGatewayProvider{
+ Type: egv1a1.ProviderTypeCustom,
+ Custom: &egv1a1.EnvoyGatewayCustomProvider{
+ Resource: egv1a1.EnvoyGatewayResourceProvider{
+ Type: egv1a1.ResourceProviderTypeFile,
+ File: &egv1a1.EnvoyGatewayFileResourceProvider{
+ Paths: []string{"a", "b"},
+ },
+ },
+ Infrastructure: &egv1a1.EnvoyGatewayInfrastructureProvider{
+ Type: egv1a1.InfrastructureProviderTypeHost,
+ },
+ },
+ },
+ },
+ },
+ expect: false,
+ },
+ {
+ name: "custom provider with file provider and unsupported infra provider",
+ eg: &egv1a1.EnvoyGateway{
+ EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
+ Gateway: egv1a1.DefaultGateway(),
+ Provider: &egv1a1.EnvoyGatewayProvider{
+ Type: egv1a1.ProviderTypeCustom,
+ Custom: &egv1a1.EnvoyGatewayCustomProvider{
+ Resource: egv1a1.EnvoyGatewayResourceProvider{
+ Type: egv1a1.ResourceProviderTypeFile,
+ File: &egv1a1.EnvoyGatewayFileResourceProvider{
+ Paths: []string{"a", "b"},
+ },
+ },
+ Infrastructure: &egv1a1.EnvoyGatewayInfrastructureProvider{
+ Type: "foobar",
+ },
+ },
+ },
+ },
+ },
+ expect: false,
+ },
+ {
+ name: "custom provider with file provider and host infra provider but no paths assign in resource",
+ eg: &egv1a1.EnvoyGateway{
+ EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
+ Gateway: egv1a1.DefaultGateway(),
+ Provider: &egv1a1.EnvoyGatewayProvider{
+ Type: egv1a1.ProviderTypeCustom,
+ Custom: &egv1a1.EnvoyGatewayCustomProvider{
+ Resource: egv1a1.EnvoyGatewayResourceProvider{
+ Type: egv1a1.ResourceProviderTypeFile,
+ File: &egv1a1.EnvoyGatewayFileResourceProvider{},
+ },
+ Infrastructure: &egv1a1.EnvoyGatewayInfrastructureProvider{
+ Type: egv1a1.InfrastructureProviderTypeHost,
+ Host: &egv1a1.EnvoyGatewayHostInfrastructureProvider{},
+ },
+ },
+ },
},
},
expect: false,
@@ -662,7 +824,6 @@ func TestValidateEnvoyGateway(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := ValidateEnvoyGateway(tc.eg)
if !tc.expect {
diff --git a/api/v1alpha1/validation/envoyproxy_validate.go b/api/v1alpha1/validation/envoyproxy_validate.go
index b4d8b6b7392..a13fdacbd3d 100644
--- a/api/v1alpha1/validation/envoyproxy_validate.go
+++ b/api/v1alpha1/validation/envoyproxy_validate.go
@@ -12,16 +12,9 @@ import (
"net/netip"
"github.com/dominikbraun/graph"
- bootstrapv3 "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3"
- clusterv3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
- "github.com/google/go-cmp/cmp"
- "google.golang.org/protobuf/testing/protocmp"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
- "github.com/envoyproxy/gateway/internal/utils/proto"
- "github.com/envoyproxy/gateway/internal/xds/bootstrap"
- _ "github.com/envoyproxy/gateway/internal/xds/extensions" // register the generated types to support protojson unmarshalling
)
// ValidateEnvoyProxy validates the provided EnvoyProxy.
@@ -38,6 +31,8 @@ func ValidateEnvoyProxy(proxy *egv1a1.EnvoyProxy) error {
}
// validateEnvoyProxySpec validates the provided EnvoyProxy spec.
+// This method validates everything except for the bootstrap section, because validating the bootstrap
+// section in this method would require calling into the internal apis, and would cause an import cycle.
func validateEnvoyProxySpec(spec *egv1a1.EnvoyProxySpec) error {
var errs []error
@@ -51,13 +46,6 @@ func validateEnvoyProxySpec(spec *egv1a1.EnvoyProxySpec) error {
errs = append(errs, validateProviderErrs...)
}
- // validate bootstrap
- if spec != nil && spec.Bootstrap != nil {
- if err := validateBootstrap(spec.Bootstrap); err != nil {
- errs = append(errs, err)
- }
- }
-
validateProxyTelemetryErrs := validateProxyTelemetry(spec)
if len(validateProxyTelemetryErrs) != 0 {
errs = append(errs, validateProxyTelemetryErrs...)
@@ -84,6 +72,14 @@ func validateProvider(spec *egv1a1.EnvoyProxySpec) []error {
if len(validateDeploymentErrs) != 0 {
errs = append(errs, validateDeploymentErrs...)
}
+ validateHpaErrors := validateHpa(spec)
+ if len(validateHpaErrors) != 0 {
+ errs = append(errs, validateHpaErrors...)
+ }
+ validatePdbErrors := validatePdb(spec)
+ if len(validatePdbErrors) != 0 {
+ errs = append(errs, validatePdbErrors...)
+ }
validateServiceErrs := validateService(spec)
if len(validateServiceErrs) != 0 {
errs = append(errs, validateServiceErrs...)
@@ -107,6 +103,36 @@ func validateDeployment(spec *egv1a1.EnvoyProxySpec) []error {
return errs
}
+func validateHpa(spec *egv1a1.EnvoyProxySpec) []error {
+ var errs []error
+ if spec.Provider.Kubernetes != nil && spec.Provider.Kubernetes.EnvoyHpa != nil {
+ if patch := spec.Provider.Kubernetes.EnvoyHpa.Patch; patch != nil {
+ if patch.Value.Raw == nil {
+ errs = append(errs, fmt.Errorf("envoy hpa patch object cannot be empty"))
+ }
+ if patch.Type != nil && *patch.Type != egv1a1.JSONMerge && *patch.Type != egv1a1.StrategicMerge {
+ errs = append(errs, fmt.Errorf("unsupported envoy hpa patch type %s", *patch.Type))
+ }
+ }
+ }
+ return errs
+}
+
+func validatePdb(spec *egv1a1.EnvoyProxySpec) []error {
+ var errs []error
+ if spec.Provider.Kubernetes != nil && spec.Provider.Kubernetes.EnvoyPDB != nil {
+ if patch := spec.Provider.Kubernetes.EnvoyPDB.Patch; patch != nil {
+ if patch.Value.Raw == nil {
+ errs = append(errs, fmt.Errorf("envoy pdb patch object cannot be empty"))
+ }
+ if patch.Type != nil && *patch.Type != egv1a1.JSONMerge && *patch.Type != egv1a1.StrategicMerge {
+ errs = append(errs, fmt.Errorf("unsupported envoy pdb patch type %s", *patch.Type))
+ }
+ }
+ }
+ return errs
+}
+
// TODO: remove this function if CEL validation became stable
func validateService(spec *egv1a1.EnvoyProxySpec) []error {
var errs []error
@@ -156,62 +182,6 @@ func validateService(spec *egv1a1.EnvoyProxySpec) []error {
return errs
}
-func validateBootstrap(boostrapConfig *egv1a1.ProxyBootstrap) error {
- // Validate user bootstrap config
- defaultBootstrap := &bootstrapv3.Bootstrap{}
- // TODO: need validate when enable prometheus?
- defaultBootstrapStr, err := bootstrap.GetRenderedBootstrapConfig(nil)
- if err != nil {
- return err
- }
- if err := proto.FromYAML([]byte(defaultBootstrapStr), defaultBootstrap); err != nil {
- return fmt.Errorf("unable to unmarshal default bootstrap: %w", err)
- }
- if err := defaultBootstrap.Validate(); err != nil {
- return fmt.Errorf("default bootstrap validation failed: %w", err)
- }
-
- // Validate user bootstrap config
- userBootstrapStr, err := bootstrap.ApplyBootstrapConfig(boostrapConfig, defaultBootstrapStr)
- if err != nil {
- return err
- }
- userBootstrap := &bootstrapv3.Bootstrap{}
- if err := proto.FromYAML([]byte(userBootstrapStr), userBootstrap); err != nil {
- return fmt.Errorf("failed to parse default bootstrap config: %w", err)
- }
- if err := userBootstrap.Validate(); err != nil {
- return fmt.Errorf("validation failed for user bootstrap: %w", err)
- }
-
- // Ensure dynamic resources config is same
- if userBootstrap.DynamicResources == nil ||
- cmp.Diff(userBootstrap.DynamicResources, defaultBootstrap.DynamicResources, protocmp.Transform()) != "" {
- return fmt.Errorf("dynamic_resources cannot be modified")
- }
-
- // Ensure that the xds_cluster config is same
- var userXdsCluster, defaultXdsCluster *clusterv3.Cluster
- for _, cluster := range userBootstrap.StaticResources.Clusters {
- if cluster.Name == "xds_cluster" {
- userXdsCluster = cluster
- break
- }
- }
- for _, cluster := range defaultBootstrap.StaticResources.Clusters {
- if cluster.Name == "xds_cluster" {
- defaultXdsCluster = cluster
- break
- }
- }
- if userXdsCluster == nil ||
- cmp.Diff(userXdsCluster.LoadAssignment, defaultXdsCluster.LoadAssignment, protocmp.Transform()) != "" {
- return fmt.Errorf("xds_cluster's loadAssigntment cannot be modified")
- }
-
- return nil
-}
-
func validateProxyTelemetry(spec *egv1a1.EnvoyProxySpec) []error {
var errs []error
diff --git a/api/v1alpha1/validation/envoyproxy_validate_test.go b/api/v1alpha1/validation/envoyproxy_validate_test.go
index 591c184fdd5..9c96792f541 100644
--- a/api/v1alpha1/validation/envoyproxy_validate_test.go
+++ b/api/v1alpha1/validation/envoyproxy_validate_test.go
@@ -6,8 +6,6 @@
package validation
import (
- // Register embed
- _ "embed"
"reflect"
"testing"
@@ -21,19 +19,6 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
)
-var (
- //go:embed testdata/valid-user-bootstrap.yaml
- validUserBootstrap string
- //go:embed testdata/merge-user-bootstrap.yaml
- mergeUserBootstrap string
- //go:embed testdata/missing-admin-address-user-bootstrap.yaml
- missingAdminAddressUserBootstrap string
- //go:embed testdata/different-dynamic-resources-user-bootstrap.yaml
- differentDynamicResourcesUserBootstrap string
- //go:embed testdata/different-xds-cluster-address-bootstrap.yaml
- differentXdsClusterAddressBootstrap string
-)
-
func TestValidateEnvoyProxy(t *testing.T) {
testCases := []struct {
name string
@@ -67,7 +52,7 @@ func TestValidateEnvoyProxy(t *testing.T) {
},
Spec: egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
- Type: egv1a1.ProviderTypeFile,
+ Type: egv1a1.ProviderTypeCustom,
},
},
},
@@ -319,97 +304,143 @@ func TestValidateEnvoyProxy(t *testing.T) {
},
expected: false,
},
-
{
- name: "valid user bootstrap replace type",
+ name: "should invalid when accesslog enabled using Text format, but `text` field being empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: egv1a1.EnvoyProxySpec{
- Bootstrap: &egv1a1.ProxyBootstrap{
- Value: validUserBootstrap,
+ Telemetry: &egv1a1.ProxyTelemetry{
+ AccessLog: &egv1a1.ProxyAccessLog{
+ Settings: []egv1a1.ProxyAccessLogSetting{
+ {
+ Format: &egv1a1.ProxyAccessLogFormat{
+ Type: egv1a1.ProxyAccessLogFormatTypeText,
+ },
+ },
+ },
+ },
},
},
},
- expected: true,
+ expected: false,
},
{
- name: "valid user bootstrap merge type",
+ name: "should invalid when accesslog enabled using File sink, but `file` field being empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: egv1a1.EnvoyProxySpec{
- Bootstrap: &egv1a1.ProxyBootstrap{
- Type: ptr.To(egv1a1.BootstrapTypeMerge),
- Value: mergeUserBootstrap,
+ Telemetry: &egv1a1.ProxyTelemetry{
+ AccessLog: &egv1a1.ProxyAccessLog{
+ Settings: []egv1a1.ProxyAccessLogSetting{
+ {
+ Format: &egv1a1.ProxyAccessLogFormat{
+ Type: egv1a1.ProxyAccessLogFormatTypeText,
+ Text: ptr.To("[%START_TIME%]"),
+ },
+ Sinks: []egv1a1.ProxyAccessLogSink{
+ {
+ Type: egv1a1.ProxyAccessLogSinkTypeFile,
+ },
+ },
+ },
+ },
+ },
},
},
},
- expected: true,
+ expected: false,
},
{
- name: "user bootstrap with missing admin address",
+ name: "should invalid when metrics type is OpenTelemetry, but `OpenTelemetry` field being empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: egv1a1.EnvoyProxySpec{
- Bootstrap: &egv1a1.ProxyBootstrap{
- Value: missingAdminAddressUserBootstrap,
+ Telemetry: &egv1a1.ProxyTelemetry{
+ Metrics: &egv1a1.ProxyMetrics{
+ Sinks: []egv1a1.ProxyMetricSink{
+ {
+ Type: egv1a1.MetricSinkTypeOpenTelemetry,
+ },
+ },
+ },
},
},
},
expected: false,
},
{
- name: "user bootstrap with different dynamic resources",
+ name: "should valid when metrics type is OpenTelemetry and `OpenTelemetry` field being not empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: egv1a1.EnvoyProxySpec{
- Bootstrap: &egv1a1.ProxyBootstrap{
- Value: differentDynamicResourcesUserBootstrap,
+ Telemetry: &egv1a1.ProxyTelemetry{
+ Metrics: &egv1a1.ProxyMetrics{
+ Sinks: []egv1a1.ProxyMetricSink{
+ {
+ Type: egv1a1.MetricSinkTypeOpenTelemetry,
+ OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{
+ Host: ptr.To("0.0.0.0"),
+ Port: 3217,
+ },
+ },
+ },
+ },
},
},
},
- expected: false,
+ expected: true,
},
{
- name: "user bootstrap with different xds_cluster endpoint",
+ name: "should be valid when service patch is empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: egv1a1.EnvoyProxySpec{
- Bootstrap: &egv1a1.ProxyBootstrap{
- Value: differentXdsClusterAddressBootstrap,
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyService: &egv1a1.KubernetesServiceSpec{
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Value: apiextensionsv1.JSON{
+ Raw: []byte{},
+ },
+ },
+ },
+ },
},
},
},
- expected: false,
+ expected: true,
},
{
- name: "should invalid when accesslog enabled using Text format, but `text` field being empty",
+ name: "should be valid when deployment patch is empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: egv1a1.EnvoyProxySpec{
- Telemetry: &egv1a1.ProxyTelemetry{
- AccessLog: &egv1a1.ProxyAccessLog{
- Settings: []egv1a1.ProxyAccessLogSetting{
- {
- Format: &egv1a1.ProxyAccessLogFormat{
- Type: egv1a1.ProxyAccessLogFormatTypeText,
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Value: apiextensionsv1.JSON{
+ Raw: []byte{},
},
},
},
@@ -417,28 +448,48 @@ func TestValidateEnvoyProxy(t *testing.T) {
},
},
},
- expected: false,
+ expected: true,
},
{
- name: "should invalid when accesslog enabled using File sink, but `file` field being empty",
+ name: "should be valid when pdb patch type and patch are empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: egv1a1.EnvoyProxySpec{
- Telemetry: &egv1a1.ProxyTelemetry{
- AccessLog: &egv1a1.ProxyAccessLog{
- Settings: []egv1a1.ProxyAccessLogSetting{
- {
- Format: &egv1a1.ProxyAccessLogFormat{
- Type: egv1a1.ProxyAccessLogFormatTypeText,
- Text: ptr.To("[%START_TIME%]"),
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyPDB: &egv1a1.KubernetesPodDisruptionBudgetSpec{
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Value: apiextensionsv1.JSON{
+ Raw: []byte{},
},
- Sinks: []egv1a1.ProxyAccessLogSink{
- {
- Type: egv1a1.ProxyAccessLogSinkTypeFile,
- },
+ },
+ },
+ },
+ },
+ },
+ },
+ expected: true,
+ },
+ {
+ name: "should be valid when pdb patch and type are set",
+ proxy: &egv1a1.EnvoyProxy{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "test",
+ Name: "test",
+ },
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyPDB: &egv1a1.KubernetesPodDisruptionBudgetSpec{
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Type: ptr.To(egv1a1.StrategicMerge),
+ Value: apiextensionsv1.JSON{
+ Raw: []byte("{}"),
},
},
},
@@ -446,21 +497,22 @@ func TestValidateEnvoyProxy(t *testing.T) {
},
},
},
- expected: false,
+ expected: true,
},
{
- name: "should invalid when metrics type is OpenTelemetry, but `OpenTelemetry` field being empty",
+ name: "should be invalid when pdb patch object is empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: egv1a1.EnvoyProxySpec{
- Telemetry: &egv1a1.ProxyTelemetry{
- Metrics: &egv1a1.ProxyMetrics{
- Sinks: []egv1a1.ProxyMetricSink{
- {
- Type: egv1a1.MetricSinkTypeOpenTelemetry,
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyPDB: &egv1a1.KubernetesPodDisruptionBudgetSpec{
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Type: ptr.To(egv1a1.StrategicMerge),
},
},
},
@@ -470,21 +522,20 @@ func TestValidateEnvoyProxy(t *testing.T) {
expected: false,
},
{
- name: "should valid when metrics type is OpenTelemetry and `OpenTelemetry` field being not empty",
+ name: "should be valid when pdb type not set",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: egv1a1.EnvoyProxySpec{
- Telemetry: &egv1a1.ProxyTelemetry{
- Metrics: &egv1a1.ProxyMetrics{
- Sinks: []egv1a1.ProxyMetricSink{
- {
- Type: egv1a1.MetricSinkTypeOpenTelemetry,
- OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{
- Host: ptr.To("0.0.0.0"),
- Port: 3217,
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyPDB: &egv1a1.KubernetesPodDisruptionBudgetSpec{
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Value: apiextensionsv1.JSON{
+ Raw: []byte("{}"),
},
},
},
@@ -495,7 +546,7 @@ func TestValidateEnvoyProxy(t *testing.T) {
expected: true,
},
{
- name: "should be invalid when service patch type is empty",
+ name: "should be valid when hpa patch and type are empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
@@ -505,7 +556,7 @@ func TestValidateEnvoyProxy(t *testing.T) {
Provider: &egv1a1.EnvoyProxyProvider{
Type: egv1a1.ProviderTypeKubernetes,
Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
- EnvoyService: &egv1a1.KubernetesServiceSpec{
+ EnvoyHpa: &egv1a1.KubernetesHorizontalPodAutoscalerSpec{
Patch: &egv1a1.KubernetesPatchSpec{
Value: apiextensionsv1.JSON{
Raw: []byte{},
@@ -519,7 +570,7 @@ func TestValidateEnvoyProxy(t *testing.T) {
expected: true,
},
{
- name: "should be invalid when deployment patch type is empty",
+ name: "should be valid when hpa patch and type are set",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
@@ -529,10 +580,57 @@ func TestValidateEnvoyProxy(t *testing.T) {
Provider: &egv1a1.EnvoyProxyProvider{
Type: egv1a1.ProviderTypeKubernetes,
Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
- EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ EnvoyHpa: &egv1a1.KubernetesHorizontalPodAutoscalerSpec{
Patch: &egv1a1.KubernetesPatchSpec{
+ Type: ptr.To(egv1a1.StrategicMerge),
Value: apiextensionsv1.JSON{
- Raw: []byte{},
+ Raw: []byte("{}"),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ expected: true,
+ },
+ {
+ name: "should be invalid when hpa patch object is empty",
+ proxy: &egv1a1.EnvoyProxy{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "test",
+ Name: "test",
+ },
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyHpa: &egv1a1.KubernetesHorizontalPodAutoscalerSpec{
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Type: ptr.To(egv1a1.StrategicMerge),
+ },
+ },
+ },
+ },
+ },
+ },
+ expected: false,
+ },
+ {
+ name: "should be valid when hpa type not set",
+ proxy: &egv1a1.EnvoyProxy{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "test",
+ Name: "test",
+ },
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyHpa: &egv1a1.KubernetesHorizontalPodAutoscalerSpec{
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Value: apiextensionsv1.JSON{
+ Raw: []byte("{}"),
},
},
},
@@ -543,7 +641,7 @@ func TestValidateEnvoyProxy(t *testing.T) {
expected: true,
},
{
- name: "should invalid when patch object is empty",
+ name: "should invalid when deployment patch object is empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
@@ -565,7 +663,7 @@ func TestValidateEnvoyProxy(t *testing.T) {
expected: false,
},
{
- name: "should valid when patch type and object are both not empty",
+ name: "should valid when deployment patch type and object are both not empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
@@ -590,7 +688,7 @@ func TestValidateEnvoyProxy(t *testing.T) {
expected: true,
},
{
- name: "should valid when patch type is empty and object is not empty",
+ name: "should valid when deployment patch type is empty and object is not empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
diff --git a/api/v1alpha1/validation/securitypolicy_validate.go b/api/v1alpha1/validation/securitypolicy_validate.go
index 628d3f80173..64425afdd6a 100644
--- a/api/v1alpha1/validation/securitypolicy_validate.go
+++ b/api/v1alpha1/validation/securitypolicy_validate.go
@@ -10,6 +10,7 @@ import (
"fmt"
"net/mail"
"net/url"
+ "strings"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/validation"
@@ -69,13 +70,21 @@ func ValidateJWTProvider(providers []egv1a1.JWTProvider) error {
case len(provider.Name) == 0:
errs = append(errs, errors.New("jwt provider cannot be an empty string"))
case len(provider.Issuer) != 0:
- // Issuer can take the format of a URL or an email address.
- if _, err := url.ParseRequestURI(provider.Issuer); err != nil {
- _, err := mail.ParseAddress(provider.Issuer)
- if err != nil {
- errs = append(errs, fmt.Errorf("invalid issuer; must be a URL or email address: %w", err))
+ switch {
+ // Issuer follows StringOrURI format based on https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1.
+ // Hence, when it contains ':', it MUST be a valid URI.
+ case strings.Contains(provider.Issuer, ":"):
+ if _, err := url.ParseRequestURI(provider.Issuer); err != nil {
+ errs = append(errs, fmt.Errorf("invalid issuer; when issuer contains ':' character, it MUST be a valid URI"))
+ }
+ // Adding reserved character for '@', to represent an email address.
+ // Hence, when it contains '@', it MUST be a valid Email Address.
+ case strings.Contains(provider.Issuer, "@"):
+ if _, err := mail.ParseAddress(provider.Issuer); err != nil {
+ errs = append(errs, fmt.Errorf("invalid issuer; when issuer contains '@' character, it MUST be a valid Email Address format: %w", err))
}
}
+
case len(provider.RemoteJWKS.URI) == 0:
errs = append(errs, fmt.Errorf("uri must be set for remote JWKS provider: %s", provider.Name))
}
diff --git a/api/v1alpha1/validation/securitypolicy_validate_test.go b/api/v1alpha1/validation/securitypolicy_validate_test.go
index 489c7644f8b..460a0edbb79 100644
--- a/api/v1alpha1/validation/securitypolicy_validate_test.go
+++ b/api/v1alpha1/validation/securitypolicy_validate_test.go
@@ -41,7 +41,7 @@ func TestValidateSecurityPolicy(t *testing.T) {
expected: false,
},
{
- name: "valid security policy with url",
+ name: "valid security policy with URI issuer",
policy: &egv1a1.SecurityPolicy{
TypeMeta: metav1.TypeMeta{
Kind: egv1a1.KindSecurityPolicy,
@@ -69,7 +69,7 @@ func TestValidateSecurityPolicy(t *testing.T) {
expected: true,
},
{
- name: "valid security policy with email",
+ name: "valid security policy with Email issuer",
policy: &egv1a1.SecurityPolicy{
TypeMeta: metav1.TypeMeta{
Kind: egv1a1.KindSecurityPolicy,
@@ -96,6 +96,34 @@ func TestValidateSecurityPolicy(t *testing.T) {
},
expected: true,
},
+ {
+ name: "valid security policy with non URI/Email Issuer",
+ policy: &egv1a1.SecurityPolicy{
+ TypeMeta: metav1.TypeMeta{
+ Kind: egv1a1.KindSecurityPolicy,
+ APIVersion: egv1a1.GroupVersion.String(),
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "test",
+ Name: "test",
+ },
+ Spec: egv1a1.SecurityPolicySpec{
+ JWT: &egv1a1.JWT{
+ Providers: []egv1a1.JWTProvider{
+ {
+ Name: "test",
+ Issuer: "foo.bar.local",
+ Audiences: []string{"foo.bar.local"},
+ RemoteJWKS: egv1a1.RemoteJWKS{
+ URI: "https://test.local/jwt/public-key/jwks.json",
+ },
+ },
+ },
+ },
+ },
+ },
+ expected: true,
+ },
{
name: "valid security policy with jwtClaimToHeader",
policy: &egv1a1.SecurityPolicy{
diff --git a/api/v1alpha1/wasm_types.go b/api/v1alpha1/wasm_types.go
index 1c41513f941..8913486d6f1 100644
--- a/api/v1alpha1/wasm_types.go
+++ b/api/v1alpha1/wasm_types.go
@@ -7,9 +7,17 @@ package v1alpha1
import (
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
- gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)
+// WasmEnv defines the environment variables for the VM of a Wasm extension
+type WasmEnv struct {
+ // HostKeys is a list of keys for environment variables from the host envoy process
+ // that should be passed into the Wasm VM. This is useful for passing secrets to to Wasm extensions.
+ // +optional
+ HostKeys []string `json:"hostKeys,omitempty"`
+}
+
// Wasm defines a Wasm extension.
//
// Note: at the moment, Envoy Gateway does not support configuring Wasm runtime.
@@ -52,6 +60,10 @@ type Wasm struct {
// Priority defines the location of the Wasm extension in the HTTP filter chain.
// If not specified, the Wasm extension will be inserted before the router filter.
// Priority *uint32 `json:"priority,omitempty"`
+
+ // Env configures the environment for the Wasm extension
+ // +optional
+ Env *WasmEnv `json:"env,omitempty"`
}
// WasmCodeSource defines the source of the Wasm code.
@@ -136,7 +148,7 @@ type ImageWasmCodeSource struct {
// Only support Kubernetes Secret resource from the same namespace.
// +kubebuilder:validation:XValidation:message="only support Secret kind.",rule="self.kind == 'Secret'"
// +optional
- PullSecretRef *gwapiv1b1.SecretObjectReference `json:"pullSecretRef,omitempty"`
+ PullSecretRef *gwapiv1.SecretObjectReference `json:"pullSecretRef,omitempty"`
}
// ImagePullPolicy defines the policy to use when pulling an OIC image.
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 3ea39b669c6..dbc28e6aca2 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -23,13 +23,7 @@ import (
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ALSEnvoyProxyAccessLog) DeepCopyInto(out *ALSEnvoyProxyAccessLog) {
*out = *in
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.LogName != nil {
in, out := &in.LogName, &out.LogName
*out = new(string)
@@ -115,6 +109,11 @@ func (in *ActiveHealthCheck) DeepCopyInto(out *ActiveHealthCheck) {
*out = new(TCPActiveHealthChecker)
(*in).DeepCopyInto(*out)
}
+ if in.GRPC != nil {
+ in, out := &in.GRPC, &out.GRPC
+ *out = new(GRPCActiveHealthChecker)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ActiveHealthCheck.
@@ -252,6 +251,38 @@ func (in *Backend) DeepCopyObject() runtime.Object {
return nil
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BackendCluster) DeepCopyInto(out *BackendCluster) {
+ *out = *in
+ if in.BackendRef != nil {
+ in, out := &in.BackendRef, &out.BackendRef
+ *out = new(apisv1.BackendObjectReference)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.BackendRefs != nil {
+ in, out := &in.BackendRefs, &out.BackendRefs
+ *out = make([]BackendRef, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.BackendSettings != nil {
+ in, out := &in.BackendSettings, &out.BackendSettings
+ *out = new(ClusterSettings)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendCluster.
+func (in *BackendCluster) DeepCopy() *BackendCluster {
+ if in == nil {
+ return nil
+ }
+ out := new(BackendCluster)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BackendConnection) DeepCopyInto(out *BackendConnection) {
*out = *in
@@ -260,6 +291,11 @@ func (in *BackendConnection) DeepCopyInto(out *BackendConnection) {
x := (*in).DeepCopy()
*out = &x
}
+ if in.SocketBufferLimit != nil {
+ in, out := &in.SocketBufferLimit, &out.SocketBufferLimit
+ x := (*in).DeepCopy()
+ *out = &x
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendConnection.
@@ -338,6 +374,11 @@ func (in *BackendList) DeepCopyObject() runtime.Object {
func (in *BackendRef) DeepCopyInto(out *BackendRef) {
*out = *in
in.BackendObjectReference.DeepCopyInto(&out.BackendObjectReference)
+ if in.Fallback != nil {
+ in, out := &in.Fallback, &out.Fallback
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendRef.
@@ -365,6 +406,11 @@ func (in *BackendSpec) DeepCopyInto(out *BackendSpec) {
*out = make([]AppProtocolType, len(*in))
copy(*out, *in)
}
+ if in.Fallback != nil {
+ in, out := &in.Fallback, &out.Fallback
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendSpec.
@@ -447,26 +493,6 @@ func (in *BackendTrafficPolicy) DeepCopyObject() runtime.Object {
return nil
}
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BackendTrafficPolicyConnection) DeepCopyInto(out *BackendTrafficPolicyConnection) {
- *out = *in
- if in.BufferLimit != nil {
- in, out := &in.BufferLimit, &out.BufferLimit
- x := (*in).DeepCopy()
- *out = &x
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTrafficPolicyConnection.
-func (in *BackendTrafficPolicyConnection) DeepCopy() *BackendTrafficPolicyConnection {
- if in == nil {
- return nil
- }
- out := new(BackendTrafficPolicyConnection)
- in.DeepCopyInto(out)
- return out
-}
-
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BackendTrafficPolicyList) DeepCopyInto(out *BackendTrafficPolicyList) {
*out = *in
@@ -503,56 +529,22 @@ func (in *BackendTrafficPolicyList) DeepCopyObject() runtime.Object {
func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) {
*out = *in
in.PolicyTargetReferences.DeepCopyInto(&out.PolicyTargetReferences)
+ in.ClusterSettings.DeepCopyInto(&out.ClusterSettings)
if in.RateLimit != nil {
in, out := &in.RateLimit, &out.RateLimit
*out = new(RateLimitSpec)
(*in).DeepCopyInto(*out)
}
- if in.LoadBalancer != nil {
- in, out := &in.LoadBalancer, &out.LoadBalancer
- *out = new(LoadBalancer)
- (*in).DeepCopyInto(*out)
- }
- if in.ProxyProtocol != nil {
- in, out := &in.ProxyProtocol, &out.ProxyProtocol
- *out = new(ProxyProtocol)
- **out = **in
- }
- if in.TCPKeepalive != nil {
- in, out := &in.TCPKeepalive, &out.TCPKeepalive
- *out = new(TCPKeepalive)
- (*in).DeepCopyInto(*out)
- }
- if in.HealthCheck != nil {
- in, out := &in.HealthCheck, &out.HealthCheck
- *out = new(HealthCheck)
- (*in).DeepCopyInto(*out)
- }
if in.FaultInjection != nil {
in, out := &in.FaultInjection, &out.FaultInjection
*out = new(FaultInjection)
(*in).DeepCopyInto(*out)
}
- if in.CircuitBreaker != nil {
- in, out := &in.CircuitBreaker, &out.CircuitBreaker
- *out = new(CircuitBreaker)
- (*in).DeepCopyInto(*out)
- }
- if in.Retry != nil {
- in, out := &in.Retry, &out.Retry
- *out = new(Retry)
- (*in).DeepCopyInto(*out)
- }
if in.UseClientProtocol != nil {
in, out := &in.UseClientProtocol, &out.UseClientProtocol
*out = new(bool)
**out = **in
}
- if in.Timeout != nil {
- in, out := &in.Timeout, &out.Timeout
- *out = new(Timeout)
- (*in).DeepCopyInto(*out)
- }
if in.Compression != nil {
in, out := &in.Compression, &out.Compression
*out = make([]*Compression, len(*in))
@@ -564,10 +556,16 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec)
}
}
}
- if in.Connection != nil {
- in, out := &in.Connection, &out.Connection
- *out = new(BackendConnection)
- (*in).DeepCopyInto(*out)
+ if in.ResponseOverride != nil {
+ in, out := &in.ResponseOverride, &out.ResponseOverride
+ *out = make([]*ResponseOverride, len(*in))
+ for i := range *in {
+ if (*in)[i] != nil {
+ in, out := &(*in)[i], &(*out)[i]
+ *out = new(ResponseOverride)
+ (*in).DeepCopyInto(*out)
+ }
+ }
}
}
@@ -597,6 +595,21 @@ func (in *BasicAuth) DeepCopy() *BasicAuth {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BodyToExtAuth) DeepCopyInto(out *BodyToExtAuth) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BodyToExtAuth.
+func (in *BodyToExtAuth) DeepCopy() *BodyToExtAuth {
+ if in == nil {
+ return nil
+ }
+ out := new(BodyToExtAuth)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CORS) DeepCopyInto(out *CORS) {
*out = *in
@@ -710,6 +723,11 @@ func (in *ClientConnection) DeepCopyInto(out *ClientConnection) {
x := (*in).DeepCopy()
*out = &x
}
+ if in.SocketBufferLimit != nil {
+ in, out := &in.SocketBufferLimit, &out.SocketBufferLimit
+ x := (*in).DeepCopy()
+ *out = &x
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientConnection.
@@ -756,6 +774,11 @@ func (in *ClientTLSSettings) DeepCopyInto(out *ClientTLSSettings) {
(*in).DeepCopyInto(*out)
}
in.TLSSettings.DeepCopyInto(&out.TLSSettings)
+ if in.Session != nil {
+ in, out := &in.Session, &out.Session
+ *out = new(Session)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientTLSSettings.
@@ -950,6 +973,71 @@ func (in *ClientValidationContext) DeepCopy() *ClientValidationContext {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ClusterSettings) DeepCopyInto(out *ClusterSettings) {
+ *out = *in
+ if in.LoadBalancer != nil {
+ in, out := &in.LoadBalancer, &out.LoadBalancer
+ *out = new(LoadBalancer)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Retry != nil {
+ in, out := &in.Retry, &out.Retry
+ *out = new(Retry)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.ProxyProtocol != nil {
+ in, out := &in.ProxyProtocol, &out.ProxyProtocol
+ *out = new(ProxyProtocol)
+ **out = **in
+ }
+ if in.TCPKeepalive != nil {
+ in, out := &in.TCPKeepalive, &out.TCPKeepalive
+ *out = new(TCPKeepalive)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.HealthCheck != nil {
+ in, out := &in.HealthCheck, &out.HealthCheck
+ *out = new(HealthCheck)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.CircuitBreaker != nil {
+ in, out := &in.CircuitBreaker, &out.CircuitBreaker
+ *out = new(CircuitBreaker)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Timeout != nil {
+ in, out := &in.Timeout, &out.Timeout
+ *out = new(Timeout)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Connection != nil {
+ in, out := &in.Connection, &out.Connection
+ *out = new(BackendConnection)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.DNS != nil {
+ in, out := &in.DNS, &out.DNS
+ *out = new(DNS)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.HTTP2 != nil {
+ in, out := &in.HTTP2, &out.HTTP2
+ *out = new(HTTP2Settings)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSettings.
+func (in *ClusterSettings) DeepCopy() *ClusterSettings {
+ if in == nil {
+ return nil
+ }
+ out := new(ClusterSettings)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Compression) DeepCopyInto(out *Compression) {
*out = *in
@@ -1067,6 +1155,79 @@ func (in *CustomHeaderExtensionSettings) DeepCopy() *CustomHeaderExtensionSettin
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomResponse) DeepCopyInto(out *CustomResponse) {
+ *out = *in
+ if in.ContentType != nil {
+ in, out := &in.ContentType, &out.ContentType
+ *out = new(string)
+ **out = **in
+ }
+ in.Body.DeepCopyInto(&out.Body)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResponse.
+func (in *CustomResponse) DeepCopy() *CustomResponse {
+ if in == nil {
+ return nil
+ }
+ out := new(CustomResponse)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomResponseBody) DeepCopyInto(out *CustomResponseBody) {
+ *out = *in
+ if in.Type != nil {
+ in, out := &in.Type, &out.Type
+ *out = new(ResponseValueType)
+ **out = **in
+ }
+ if in.Inline != nil {
+ in, out := &in.Inline, &out.Inline
+ *out = new(string)
+ **out = **in
+ }
+ if in.ValueRef != nil {
+ in, out := &in.ValueRef, &out.ValueRef
+ *out = new(apisv1.LocalObjectReference)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResponseBody.
+func (in *CustomResponseBody) DeepCopy() *CustomResponseBody {
+ if in == nil {
+ return nil
+ }
+ out := new(CustomResponseBody)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomResponseMatch) DeepCopyInto(out *CustomResponseMatch) {
+ *out = *in
+ if in.StatusCodes != nil {
+ in, out := &in.StatusCodes, &out.StatusCodes
+ *out = make([]StatusCodeMatch, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResponseMatch.
+func (in *CustomResponseMatch) DeepCopy() *CustomResponseMatch {
+ if in == nil {
+ return nil
+ }
+ out := new(CustomResponseMatch)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomTag) DeepCopyInto(out *CustomTag) {
*out = *in
@@ -1097,6 +1258,31 @@ func (in *CustomTag) DeepCopy() *CustomTag {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DNS) DeepCopyInto(out *DNS) {
+ *out = *in
+ if in.DNSRefreshRate != nil {
+ in, out := &in.DNSRefreshRate, &out.DNSRefreshRate
+ *out = new(v1.Duration)
+ **out = **in
+ }
+ if in.RespectDNSTTL != nil {
+ in, out := &in.RespectDNSTTL, &out.RespectDNSTTL
+ *out = new(bool)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNS.
+func (in *DNS) DeepCopy() *DNS {
+ if in == nil {
+ return nil
+ }
+ out := new(DNS)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EnvironmentCustomTag) DeepCopyInto(out *EnvironmentCustomTag) {
*out = *in
@@ -1270,7 +1456,11 @@ func (in *EnvoyGatewayAdminAddress) DeepCopy() *EnvoyGatewayAdminAddress {
func (in *EnvoyGatewayCustomProvider) DeepCopyInto(out *EnvoyGatewayCustomProvider) {
*out = *in
in.Resource.DeepCopyInto(&out.Resource)
- in.Infrastructure.DeepCopyInto(&out.Infrastructure)
+ if in.Infrastructure != nil {
+ in, out := &in.Infrastructure, &out.Infrastructure
+ *out = new(EnvoyGatewayInfrastructureProvider)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyGatewayCustomProvider.
@@ -1890,6 +2080,11 @@ func (in *EnvoyProxySpec) DeepCopyInto(out *EnvoyProxySpec) {
*out = new(BackendTLSConfig)
(*in).DeepCopyInto(*out)
}
+ if in.IPFamily != nil {
+ in, out := &in.IPFamily, &out.IPFamily
+ *out = new(IPFamily)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyProxySpec.
@@ -1935,11 +2130,21 @@ func (in *ExtAuth) DeepCopyInto(out *ExtAuth) {
*out = make([]string, len(*in))
copy(*out, *in)
}
+ if in.BodyToExtAuth != nil {
+ in, out := &in.BodyToExtAuth, &out.BodyToExtAuth
+ *out = new(BodyToExtAuth)
+ **out = **in
+ }
if in.FailOpen != nil {
in, out := &in.FailOpen, &out.FailOpen
*out = new(bool)
**out = **in
}
+ if in.RecomputeRoute != nil {
+ in, out := &in.RecomputeRoute, &out.RecomputeRoute
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtAuth.
@@ -1955,13 +2160,7 @@ func (in *ExtAuth) DeepCopy() *ExtAuth {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExtProc) DeepCopyInto(out *ExtProc) {
*out = *in
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.MessageTimeout != nil {
in, out := &in.MessageTimeout, &out.MessageTimeout
*out = new(apisv1.Duration)
@@ -2257,20 +2456,29 @@ func (in *FilterPosition) DeepCopy() *FilterPosition {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *GRPCExtAuthService) DeepCopyInto(out *GRPCExtAuthService) {
+func (in *GRPCActiveHealthChecker) DeepCopyInto(out *GRPCActiveHealthChecker) {
*out = *in
- if in.BackendRef != nil {
- in, out := &in.BackendRef, &out.BackendRef
- *out = new(apisv1.BackendObjectReference)
- (*in).DeepCopyInto(*out)
+ if in.Service != nil {
+ in, out := &in.Service, &out.Service
+ *out = new(string)
+ **out = **in
}
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCActiveHealthChecker.
+func (in *GRPCActiveHealthChecker) DeepCopy() *GRPCActiveHealthChecker {
+ if in == nil {
+ return nil
}
+ out := new(GRPCActiveHealthChecker)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GRPCExtAuthService) DeepCopyInto(out *GRPCExtAuthService) {
+ *out = *in
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCExtAuthService.
@@ -2418,6 +2626,11 @@ func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) {
*out = new(uint32)
**out = **in
}
+ if in.OnInvalidMessage != nil {
+ in, out := &in.OnInvalidMessage, &out.OnInvalidMessage
+ *out = new(InvalidMessageAction)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2Settings.
@@ -2501,20 +2714,39 @@ func (in *HTTPClientTimeout) DeepCopy() *HTTPClientTimeout {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *HTTPExtAuthService) DeepCopyInto(out *HTTPExtAuthService) {
+func (in *HTTPDirectResponseFilter) DeepCopyInto(out *HTTPDirectResponseFilter) {
*out = *in
- if in.BackendRef != nil {
- in, out := &in.BackendRef, &out.BackendRef
- *out = new(apisv1.BackendObjectReference)
+ if in.ContentType != nil {
+ in, out := &in.ContentType, &out.ContentType
+ *out = new(string)
+ **out = **in
+ }
+ if in.Body != nil {
+ in, out := &in.Body, &out.Body
+ *out = new(CustomResponseBody)
(*in).DeepCopyInto(*out)
}
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
+ if in.StatusCode != nil {
+ in, out := &in.StatusCode, &out.StatusCode
+ *out = new(int)
+ **out = **in
}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPDirectResponseFilter.
+func (in *HTTPDirectResponseFilter) DeepCopy() *HTTPDirectResponseFilter {
+ if in == nil {
+ return nil
+ }
+ out := new(HTTPDirectResponseFilter)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HTTPExtAuthService) DeepCopyInto(out *HTTPExtAuthService) {
+ *out = *in
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.Path != nil {
in, out := &in.Path, &out.Path
*out = new(string)
@@ -2537,6 +2769,129 @@ func (in *HTTPExtAuthService) DeepCopy() *HTTPExtAuthService {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HTTPHostnameModifier) DeepCopyInto(out *HTTPHostnameModifier) {
+ *out = *in
+ if in.Header != nil {
+ in, out := &in.Header, &out.Header
+ *out = new(string)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHostnameModifier.
+func (in *HTTPHostnameModifier) DeepCopy() *HTTPHostnameModifier {
+ if in == nil {
+ return nil
+ }
+ out := new(HTTPHostnameModifier)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HTTPPathModifier) DeepCopyInto(out *HTTPPathModifier) {
+ *out = *in
+ if in.ReplaceRegexMatch != nil {
+ in, out := &in.ReplaceRegexMatch, &out.ReplaceRegexMatch
+ *out = new(ReplaceRegexMatch)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPPathModifier.
+func (in *HTTPPathModifier) DeepCopy() *HTTPPathModifier {
+ if in == nil {
+ return nil
+ }
+ out := new(HTTPPathModifier)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HTTPRouteFilter) DeepCopyInto(out *HTTPRouteFilter) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteFilter.
+func (in *HTTPRouteFilter) DeepCopy() *HTTPRouteFilter {
+ if in == nil {
+ return nil
+ }
+ out := new(HTTPRouteFilter)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *HTTPRouteFilter) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HTTPRouteFilterList) DeepCopyInto(out *HTTPRouteFilterList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]HTTPRouteFilter, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteFilterList.
+func (in *HTTPRouteFilterList) DeepCopy() *HTTPRouteFilterList {
+ if in == nil {
+ return nil
+ }
+ out := new(HTTPRouteFilterList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *HTTPRouteFilterList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HTTPRouteFilterSpec) DeepCopyInto(out *HTTPRouteFilterSpec) {
+ *out = *in
+ if in.URLRewrite != nil {
+ in, out := &in.URLRewrite, &out.URLRewrite
+ *out = new(HTTPURLRewriteFilter)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.DirectResponse != nil {
+ in, out := &in.DirectResponse, &out.DirectResponse
+ *out = new(HTTPDirectResponseFilter)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteFilterSpec.
+func (in *HTTPRouteFilterSpec) DeepCopy() *HTTPRouteFilterSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(HTTPRouteFilterSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HTTPTimeout) DeepCopyInto(out *HTTPTimeout) {
*out = *in
@@ -2550,14 +2905,44 @@ func (in *HTTPTimeout) DeepCopyInto(out *HTTPTimeout) {
*out = new(apisv1.Duration)
**out = **in
}
+ if in.RequestTimeout != nil {
+ in, out := &in.RequestTimeout, &out.RequestTimeout
+ *out = new(apisv1.Duration)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPTimeout.
+func (in *HTTPTimeout) DeepCopy() *HTTPTimeout {
+ if in == nil {
+ return nil
+ }
+ out := new(HTTPTimeout)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HTTPURLRewriteFilter) DeepCopyInto(out *HTTPURLRewriteFilter) {
+ *out = *in
+ if in.Hostname != nil {
+ in, out := &in.Hostname, &out.Hostname
+ *out = new(HTTPHostnameModifier)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Path != nil {
+ in, out := &in.Path, &out.Path
+ *out = new(HTTPPathModifier)
+ (*in).DeepCopyInto(*out)
+ }
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPTimeout.
-func (in *HTTPTimeout) DeepCopy() *HTTPTimeout {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPURLRewriteFilter.
+func (in *HTTPURLRewriteFilter) DeepCopy() *HTTPURLRewriteFilter {
if in == nil {
return nil
}
- out := new(HTTPTimeout)
+ out := new(HTTPURLRewriteFilter)
in.DeepCopyInto(out)
return out
}
@@ -2610,6 +2995,11 @@ func (in *HeaderMatch) DeepCopyInto(out *HeaderMatch) {
*out = new(string)
**out = **in
}
+ if in.Invert != nil {
+ in, out := &in.Invert, &out.Invert
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderMatch.
@@ -2650,6 +3040,11 @@ func (in *HeaderSettings) DeepCopyInto(out *HeaderSettings) {
*out = new(bool)
**out = **in
}
+ if in.EarlyRequestHeaders != nil {
+ in, out := &in.EarlyRequestHeaders, &out.EarlyRequestHeaders
+ *out = new(apisv1.HTTPHeaderFilter)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderSettings.
@@ -2745,6 +3140,16 @@ func (in *ImageWasmCodeSource) DeepCopy() *ImageWasmCodeSource {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONPatchOperation) DeepCopyInto(out *JSONPatchOperation) {
*out = *in
+ if in.Path != nil {
+ in, out := &in.Path, &out.Path
+ *out = new(string)
+ **out = **in
+ }
+ if in.JSONPath != nil {
+ in, out := &in.JSONPath, &out.JSONPath
+ *out = new(string)
+ **out = **in
+ }
if in.From != nil {
in, out := &in.From, &out.From
*out = new(string)
@@ -2794,6 +3199,31 @@ func (in *JWT) DeepCopy() *JWT {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JWTClaim) DeepCopyInto(out *JWTClaim) {
+ *out = *in
+ if in.ValueType != nil {
+ in, out := &in.ValueType, &out.ValueType
+ *out = new(JWTClaimValueType)
+ **out = **in
+ }
+ if in.Values != nil {
+ in, out := &in.Values, &out.Values
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JWTClaim.
+func (in *JWTClaim) DeepCopy() *JWTClaim {
+ if in == nil {
+ return nil
+ }
+ out := new(JWTClaim)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JWTExtractor) DeepCopyInto(out *JWTExtractor) {
*out = *in
@@ -2846,6 +3276,33 @@ func (in *JWTHeaderExtractor) DeepCopy() *JWTHeaderExtractor {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JWTPrincipal) DeepCopyInto(out *JWTPrincipal) {
+ *out = *in
+ if in.Claims != nil {
+ in, out := &in.Claims, &out.Claims
+ *out = make([]JWTClaim, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.Scopes != nil {
+ in, out := &in.Scopes, &out.Scopes
+ *out = make([]JWTScope, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JWTPrincipal.
+func (in *JWTPrincipal) DeepCopy() *JWTPrincipal {
+ if in == nil {
+ return nil
+ }
+ out := new(JWTPrincipal)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JWTProvider) DeepCopyInto(out *JWTProvider) {
*out = *in
@@ -3058,6 +3515,11 @@ func (in *KubernetesHorizontalPodAutoscalerSpec) DeepCopyInto(out *KubernetesHor
*out = new(v2.HorizontalPodAutoscalerBehavior)
(*in).DeepCopyInto(*out)
}
+ if in.Patch != nil {
+ in, out := &in.Patch, &out.Patch
+ *out = new(KubernetesPatchSpec)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesHorizontalPodAutoscalerSpec.
@@ -3099,6 +3561,11 @@ func (in *KubernetesPodDisruptionBudgetSpec) DeepCopyInto(out *KubernetesPodDisr
*out = new(int32)
**out = **in
}
+ if in.Patch != nil {
+ in, out := &in.Patch, &out.Patch
+ *out = new(KubernetesPatchSpec)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesPodDisruptionBudgetSpec.
@@ -3193,6 +3660,13 @@ func (in *KubernetesServiceSpec) DeepCopyInto(out *KubernetesServiceSpec) {
(*out)[key] = val
}
}
+ if in.Labels != nil {
+ in, out := &in.Labels, &out.Labels
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
if in.Type != nil {
in, out := &in.Type, &out.Type
*out = new(ServiceType)
@@ -3377,6 +3851,11 @@ func (in *OIDC) DeepCopyInto(out *OIDC) {
*out = new(OIDCCookieNames)
(*in).DeepCopyInto(*out)
}
+ if in.CookieDomain != nil {
+ in, out := &in.CookieDomain, &out.CookieDomain
+ *out = new(string)
+ **out = **in
+ }
if in.Scopes != nil {
in, out := &in.Scopes, &out.Scopes
*out = make([]string, len(*in))
@@ -3457,6 +3936,7 @@ func (in *OIDCCookieNames) DeepCopy() *OIDCCookieNames {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OIDCProvider) DeepCopyInto(out *OIDCProvider) {
*out = *in
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.AuthorizationEndpoint != nil {
in, out := &in.AuthorizationEndpoint, &out.AuthorizationEndpoint
*out = new(string)
@@ -3482,18 +3962,12 @@ func (in *OIDCProvider) DeepCopy() *OIDCProvider {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OpenTelemetryEnvoyProxyAccessLog) DeepCopyInto(out *OpenTelemetryEnvoyProxyAccessLog) {
*out = *in
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.Host != nil {
in, out := &in.Host, &out.Host
*out = new(string)
**out = **in
}
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
if in.Resources != nil {
in, out := &in.Resources, &out.Resources
*out = make(map[string]string, len(*in))
@@ -3655,6 +4129,11 @@ func (in *Principal) DeepCopyInto(out *Principal) {
*out = make([]CIDR, len(*in))
copy(*out, *in)
}
+ if in.JWT != nil {
+ in, out := &in.JWT, &out.JWT
+ *out = new(JWTPrincipal)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Principal.
@@ -3675,6 +4154,11 @@ func (in *ProcessingModeOptions) DeepCopyInto(out *ProcessingModeOptions) {
*out = new(ExtProcBodyProcessingMode)
**out = **in
}
+ if in.Attributes != nil {
+ in, out := &in.Attributes, &out.Attributes
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProcessingModeOptions.
@@ -3756,6 +4240,11 @@ func (in *ProxyAccessLogSetting) DeepCopyInto(out *ProxyAccessLogSetting) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
+ if in.Type != nil {
+ in, out := &in.Type, &out.Type
+ *out = new(ProxyAccessLogType)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyAccessLogSetting.
@@ -3806,6 +4295,18 @@ func (in *ProxyBootstrap) DeepCopyInto(out *ProxyBootstrap) {
*out = new(BootstrapType)
**out = **in
}
+ if in.Value != nil {
+ in, out := &in.Value, &out.Value
+ *out = new(string)
+ **out = **in
+ }
+ if in.JSONPatches != nil {
+ in, out := &in.JSONPatches, &out.JSONPatches
+ *out = make([]JSONPatchOperation, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyBootstrap.
@@ -3882,6 +4383,21 @@ func (in *ProxyMetrics) DeepCopyInto(out *ProxyMetrics) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
+ if in.EnableVirtualHostStats != nil {
+ in, out := &in.EnableVirtualHostStats, &out.EnableVirtualHostStats
+ *out = new(bool)
+ **out = **in
+ }
+ if in.EnablePerEndpointStats != nil {
+ in, out := &in.EnablePerEndpointStats, &out.EnablePerEndpointStats
+ *out = new(bool)
+ **out = **in
+ }
+ if in.EnableRequestResponseSizesStats != nil {
+ in, out := &in.EnableRequestResponseSizesStats, &out.EnableRequestResponseSizesStats
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyMetrics.
@@ -3897,18 +4413,12 @@ func (in *ProxyMetrics) DeepCopy() *ProxyMetrics {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ProxyOpenTelemetrySink) DeepCopyInto(out *ProxyOpenTelemetrySink) {
*out = *in
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.Host != nil {
in, out := &in.Host, &out.Host
*out = new(string)
**out = **in
}
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyOpenTelemetrySink.
@@ -4310,6 +4820,21 @@ func (in *RemoteJWKS) DeepCopy() *RemoteJWKS {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ReplaceRegexMatch) DeepCopyInto(out *ReplaceRegexMatch) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplaceRegexMatch.
+func (in *ReplaceRegexMatch) DeepCopy() *ReplaceRegexMatch {
+ if in == nil {
+ return nil
+ }
+ out := new(ReplaceRegexMatch)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RequestHeaderCustomTag) DeepCopyInto(out *RequestHeaderCustomTag) {
*out = *in
@@ -4330,6 +4855,23 @@ func (in *RequestHeaderCustomTag) DeepCopy() *RequestHeaderCustomTag {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ResponseOverride) DeepCopyInto(out *ResponseOverride) {
+ *out = *in
+ in.Match.DeepCopyInto(&out.Match)
+ in.Response.DeepCopyInto(&out.Response)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResponseOverride.
+func (in *ResponseOverride) DeepCopy() *ResponseOverride {
+ if in == nil {
+ return nil
+ }
+ out := new(ResponseOverride)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Retry) DeepCopyInto(out *Retry) {
*out = *in
@@ -4490,6 +5032,51 @@ func (in *SecurityPolicySpec) DeepCopy() *SecurityPolicySpec {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Session) DeepCopyInto(out *Session) {
+ *out = *in
+ if in.Resumption != nil {
+ in, out := &in.Resumption, &out.Resumption
+ *out = new(SessionResumption)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Session.
+func (in *Session) DeepCopy() *Session {
+ if in == nil {
+ return nil
+ }
+ out := new(Session)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SessionResumption) DeepCopyInto(out *SessionResumption) {
+ *out = *in
+ if in.Stateless != nil {
+ in, out := &in.Stateless, &out.Stateless
+ *out = new(StatelessTLSSessionResumption)
+ **out = **in
+ }
+ if in.Stateful != nil {
+ in, out := &in.Stateful, &out.Stateful
+ *out = new(StatefulTLSSessionResumption)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SessionResumption.
+func (in *SessionResumption) DeepCopy() *SessionResumption {
+ if in == nil {
+ return nil
+ }
+ out := new(SessionResumption)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ShutdownConfig) DeepCopyInto(out *ShutdownConfig) {
*out = *in
@@ -4575,6 +5162,81 @@ func (in *SourceMatch) DeepCopy() *SourceMatch {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StatefulTLSSessionResumption) DeepCopyInto(out *StatefulTLSSessionResumption) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulTLSSessionResumption.
+func (in *StatefulTLSSessionResumption) DeepCopy() *StatefulTLSSessionResumption {
+ if in == nil {
+ return nil
+ }
+ out := new(StatefulTLSSessionResumption)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StatelessTLSSessionResumption) DeepCopyInto(out *StatelessTLSSessionResumption) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatelessTLSSessionResumption.
+func (in *StatelessTLSSessionResumption) DeepCopy() *StatelessTLSSessionResumption {
+ if in == nil {
+ return nil
+ }
+ out := new(StatelessTLSSessionResumption)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StatusCodeMatch) DeepCopyInto(out *StatusCodeMatch) {
+ *out = *in
+ if in.Type != nil {
+ in, out := &in.Type, &out.Type
+ *out = new(StatusCodeValueType)
+ **out = **in
+ }
+ if in.Value != nil {
+ in, out := &in.Value, &out.Value
+ *out = new(int)
+ **out = **in
+ }
+ if in.Range != nil {
+ in, out := &in.Range, &out.Range
+ *out = new(StatusCodeRange)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusCodeMatch.
+func (in *StatusCodeMatch) DeepCopy() *StatusCodeMatch {
+ if in == nil {
+ return nil
+ }
+ out := new(StatusCodeMatch)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StatusCodeRange) DeepCopyInto(out *StatusCodeRange) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusCodeRange.
+func (in *StatusCodeRange) DeepCopy() *StatusCodeRange {
+ if in == nil {
+ return nil
+ }
+ out := new(StatusCodeRange)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StringMatch) DeepCopyInto(out *StringMatch) {
*out = *in
@@ -4790,18 +5452,12 @@ func (in *Timeout) DeepCopy() *Timeout {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TracingProvider) DeepCopyInto(out *TracingProvider) {
*out = *in
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.Host != nil {
in, out := &in.Host, &out.Host
*out = new(string)
**out = **in
}
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
if in.Zipkin != nil {
in, out := &in.Zipkin, &out.Zipkin
*out = new(ZipkinTracingProvider)
@@ -4858,6 +5514,11 @@ func (in *Wasm) DeepCopyInto(out *Wasm) {
*out = new(bool)
**out = **in
}
+ if in.Env != nil {
+ in, out := &in.Env, &out.Env
+ *out = new(WasmEnv)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Wasm.
@@ -4900,6 +5561,26 @@ func (in *WasmCodeSource) DeepCopy() *WasmCodeSource {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *WasmEnv) DeepCopyInto(out *WasmEnv) {
+ *out = *in
+ if in.HostKeys != nil {
+ in, out := &in.HostKeys, &out.HostKeys
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WasmEnv.
+func (in *WasmEnv) DeepCopy() *WasmEnv {
+ if in == nil {
+ return nil
+ }
+ out := new(WasmEnv)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *XDSTranslatorHooks) DeepCopyInto(out *XDSTranslatorHooks) {
*out = *in
@@ -4958,6 +5639,11 @@ func (in *XForwardedForSettings) DeepCopyInto(out *XForwardedForSettings) {
*out = new(uint32)
**out = **in
}
+ if in.TrustedCIDRs != nil {
+ in, out := &in.TrustedCIDRs, &out.TrustedCIDRs
+ *out = make([]CIDR, len(*in))
+ copy(*out, *in)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XForwardedForSettings.
diff --git a/charts/gateway-addons-helm/Chart.lock b/charts/gateway-addons-helm/Chart.lock
index 4b6f92ac77c..4e15b355cb5 100644
--- a/charts/gateway-addons-helm/Chart.lock
+++ b/charts/gateway-addons-helm/Chart.lock
@@ -8,6 +8,9 @@ dependencies:
- name: fluent-bit
repository: https://fluent.github.io/helm-charts
version: 0.30.4
+- name: alloy
+ repository: https://grafana.github.io/helm-charts
+ version: 0.9.2
- name: loki
repository: https://grafana.github.io/helm-charts
version: 4.8.0
@@ -16,6 +19,6 @@ dependencies:
version: 1.3.1
- name: opentelemetry-collector
repository: https://open-telemetry.github.io/opentelemetry-helm-charts
- version: 0.73.1
-digest: sha256:4c16df8d7efc27aff566fa5dfd2eba6527adbf3fc8e94e7e3ccfc0cee7836f1c
-generated: "2024-06-20T11:46:59.148579+08:00"
+ version: 0.108.0
+digest: sha256:bc634c59972bfd4a01e0f4310a4949095752e659a9b5cb1d9c0fbe9a86f37011
+generated: "2024-10-25T10:55:26.755739+08:00"
diff --git a/charts/gateway-addons-helm/Chart.yaml b/charts/gateway-addons-helm/Chart.yaml
index 84ac6228f62..3a2303ef8c9 100644
--- a/charts/gateway-addons-helm/Chart.yaml
+++ b/charts/gateway-addons-helm/Chart.yaml
@@ -37,6 +37,10 @@ dependencies:
repository: https://fluent.github.io/helm-charts
version: 0.30.4
condition: fluent-bit.enabled
+ - name: alloy
+ repository: https://grafana.github.io/helm-charts
+ version: 0.9.2
+ condition: alloy.enabled
- name: loki
version: 4.8.0
repository: https://grafana.github.io/helm-charts
@@ -47,5 +51,5 @@ dependencies:
condition: tempo.enabled
- name: opentelemetry-collector
repository: https://open-telemetry.github.io/opentelemetry-helm-charts
- version: 0.73.1
+ version: 0.108.0
condition: opentelemetry-collector.enabled
diff --git a/charts/gateway-addons-helm/README.md b/charts/gateway-addons-helm/README.md
index 43082172180..b30a535e724 100644
--- a/charts/gateway-addons-helm/README.md
+++ b/charts/gateway-addons-helm/README.md
@@ -22,10 +22,11 @@ An Add-ons Helm chart for Envoy Gateway
| Repository | Name | Version |
|------------|------|---------|
| https://fluent.github.io/helm-charts | fluent-bit | 0.30.4 |
+| https://grafana.github.io/helm-charts | alloy | 0.9.2 |
| https://grafana.github.io/helm-charts | grafana | 8.0.0 |
| https://grafana.github.io/helm-charts | loki | 4.8.0 |
| https://grafana.github.io/helm-charts | tempo | 1.3.1 |
-| https://open-telemetry.github.io/opentelemetry-helm-charts | opentelemetry-collector | 0.73.1 |
+| https://open-telemetry.github.io/opentelemetry-helm-charts | opentelemetry-collector | 0.108.0 |
| https://prometheus-community.github.io/helm-charts | prometheus | 25.21.0 |
## Usage
@@ -55,6 +56,9 @@ To uninstall the chart:
| Key | Type | Default | Description |
|-----|------|---------|-------------|
+| alloy.alloy.configMap.content | string | `"// Write your Alloy config here:\nlogging {\n level = \"info\"\n format = \"logfmt\"\n}\nloki.write \"alloy\" {\n endpoint {\n url = \"http://loki.monitoring.svc:3100/loki/api/v1/push\"\n }\n}\n// discovery.kubernetes allows you to find scrape targets from Kubernetes resources.\n// It watches cluster state and ensures targets are continually synced with what is currently running in your cluster.\ndiscovery.kubernetes \"pod\" {\n role = \"pod\"\n}\n\n// discovery.relabel rewrites the label set of the input targets by applying one or more relabeling rules.\n// If no rules are defined, then the input targets are exported as-is.\ndiscovery.relabel \"pod_logs\" {\n targets = discovery.kubernetes.pod.targets\n\n // Label creation - \"namespace\" field from \"__meta_kubernetes_namespace\"\n rule {\n source_labels = [\"__meta_kubernetes_namespace\"]\n action = \"replace\"\n target_label = \"namespace\"\n }\n\n // Label creation - \"pod\" field from \"__meta_kubernetes_pod_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_name\"]\n action = \"replace\"\n target_label = \"pod\"\n }\n\n // Label creation - \"container\" field from \"__meta_kubernetes_pod_container_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"container\"\n }\n\n // Label creation - \"app\" field from \"__meta_kubernetes_pod_label_app_kubernetes_io_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_label_app_kubernetes_io_name\"]\n action = \"replace\"\n target_label = \"app\"\n }\n\n // Label creation - \"job\" field from \"__meta_kubernetes_namespace\" and \"__meta_kubernetes_pod_container_name\"\n // Concatenate values __meta_kubernetes_namespace/__meta_kubernetes_pod_container_name\n rule {\n source_labels = [\"__meta_kubernetes_namespace\", \"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"job\"\n separator = \"/\"\n replacement = \"$1\"\n }\n\n // Label creation - \"container\" field from \"__meta_kubernetes_pod_uid\" and \"__meta_kubernetes_pod_container_name\"\n // Concatenate values __meta_kubernetes_pod_uid/__meta_kubernetes_pod_container_name.log\n rule {\n source_labels = [\"__meta_kubernetes_pod_uid\", \"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"__path__\"\n separator = \"/\"\n replacement = \"/var/log/pods/*$1/*.log\"\n }\n\n // Label creation - \"container_runtime\" field from \"__meta_kubernetes_pod_container_id\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_container_id\"]\n action = \"replace\"\n target_label = \"container_runtime\"\n regex = \"^(\\\\S+):\\\\/\\\\/.+$\"\n replacement = \"$1\"\n }\n}\n\n// loki.source.kubernetes tails logs from Kubernetes containers using the Kubernetes API.\nloki.source.kubernetes \"pod_logs\" {\n targets = discovery.relabel.pod_logs.output\n forward_to = [loki.process.pod_logs.receiver]\n}\n// loki.process receives log entries from other Loki components, applies one or more processing stages,\n// and forwards the results to the list of receivers in the component’s arguments.\nloki.process \"pod_logs\" {\n stage.static_labels {\n values = {\n cluster = \"envoy-gateway\",\n }\n }\n\n forward_to = [loki.write.alloy.receiver]\n}"` | |
+| alloy.enabled | bool | `false` | |
+| alloy.fullnameOverride | string | `"alloy"` | |
| fluent-bit.config.filters | string | `"[FILTER]\n Name kubernetes\n Match kube.*\n Merge_Log On\n Keep_Log Off\n K8S-Logging.Parser On\n K8S-Logging.Exclude On\n\n[FILTER]\n Name grep\n Match kube.*\n Regex $kubernetes['container_name'] ^envoy$\n\n[FILTER]\n Name parser\n Match kube.*\n Key_Name log\n Parser envoy\n Reserve_Data True\n"` | |
| fluent-bit.config.inputs | string | `"[INPUT]\n Name tail\n Path /var/log/containers/*.log\n multiline.parser docker, cri\n Tag kube.*\n Mem_Buf_Limit 5MB\n Skip_Long_Lines On\n"` | |
| fluent-bit.config.outputs | string | `"[OUTPUT]\n Name loki\n Match kube.*\n Host loki.monitoring.svc.cluster.local\n Port 3100\n Labels job=fluentbit, app=$kubernetes['labels']['app'], k8s_namespace_name=$kubernetes['namespace_name'], k8s_pod_name=$kubernetes['pod_name'], k8s_container_name=$kubernetes['container_name']\n"` | |
@@ -84,6 +88,7 @@ To uninstall the chart:
| grafana.enabled | bool | `true` | |
| grafana.fullnameOverride | string | `"grafana"` | |
| grafana.service.type | string | `"LoadBalancer"` | |
+| grafana.testFramework.enabled | bool | `false` | |
| loki.backend.replicas | int | `0` | |
| loki.deploymentMode | string | `"SingleBinary"` | |
| loki.enabled | bool | `true` | |
@@ -102,29 +107,40 @@ To uninstall the chart:
| loki.singleBinary.replicas | int | `1` | |
| loki.test.enabled | bool | `false` | |
| loki.write.replicas | int | `0` | |
-| opentelemetry-collector.config.exporters.logging.verbosity | string | `"detailed"` | |
+| opentelemetry-collector.config.exporters.debug.verbosity | string | `"detailed"` | |
| opentelemetry-collector.config.exporters.loki.endpoint | string | `"http://loki.monitoring.svc:3100/loki/api/v1/push"` | |
| opentelemetry-collector.config.exporters.otlp.endpoint | string | `"tempo.monitoring.svc:4317"` | |
| opentelemetry-collector.config.exporters.otlp.tls.insecure | bool | `true` | |
-| opentelemetry-collector.config.exporters.prometheus.endpoint | string | `"0.0.0.0:19001"` | |
-| opentelemetry-collector.config.extensions.health_check | object | `{}` | |
+| opentelemetry-collector.config.exporters.prometheus.endpoint | string | `"[${env:MY_POD_IP}]:19001"` | |
+| opentelemetry-collector.config.extensions.health_check.endpoint | string | `"[${env:MY_POD_IP}]:13133"` | |
| opentelemetry-collector.config.processors.attributes.actions[0].action | string | `"insert"` | |
| opentelemetry-collector.config.processors.attributes.actions[0].key | string | `"loki.attribute.labels"` | |
| opentelemetry-collector.config.processors.attributes.actions[0].value | string | `"k8s.pod.name, k8s.namespace.name"` | |
-| opentelemetry-collector.config.receivers.otlp.protocols.grpc.endpoint | string | `"${env:MY_POD_IP}:4317"` | |
-| opentelemetry-collector.config.receivers.otlp.protocols.http.endpoint | string | `"${env:MY_POD_IP}:4318"` | |
-| opentelemetry-collector.config.receivers.zipkin.endpoint | string | `"${env:MY_POD_IP}:9411"` | |
+| opentelemetry-collector.config.receivers.datadog.endpoint | string | `"[${env:MY_POD_IP}]:8126"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.grpc.endpoint | string | `"[${env:MY_POD_IP}]:14250"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.thrift_compact.endpoint | string | `"[${env:MY_POD_IP}]:6831"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.thrift_http.endpoint | string | `"[${env:MY_POD_IP}]:14268"` | |
+| opentelemetry-collector.config.receivers.otlp.protocols.grpc.endpoint | string | `"[${env:MY_POD_IP}]:4317"` | |
+| opentelemetry-collector.config.receivers.otlp.protocols.http.endpoint | string | `"[${env:MY_POD_IP}]:4318"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].job_name | string | `"opentelemetry-collector"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].scrape_interval | string | `"10s"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].static_configs[0].targets[0] | string | `"[${env:MY_POD_IP}]:8888"` | |
+| opentelemetry-collector.config.receivers.zipkin.endpoint | string | `"[${env:MY_POD_IP}]:9411"` | |
| opentelemetry-collector.config.service.extensions[0] | string | `"health_check"` | |
| opentelemetry-collector.config.service.pipelines.logs.exporters[0] | string | `"loki"` | |
| opentelemetry-collector.config.service.pipelines.logs.processors[0] | string | `"attributes"` | |
| opentelemetry-collector.config.service.pipelines.logs.receivers[0] | string | `"otlp"` | |
| opentelemetry-collector.config.service.pipelines.metrics.exporters[0] | string | `"prometheus"` | |
-| opentelemetry-collector.config.service.pipelines.metrics.receivers[0] | string | `"otlp"` | |
+| opentelemetry-collector.config.service.pipelines.metrics.receivers[0] | string | `"datadog"` | |
+| opentelemetry-collector.config.service.pipelines.metrics.receivers[1] | string | `"otlp"` | |
| opentelemetry-collector.config.service.pipelines.traces.exporters[0] | string | `"otlp"` | |
-| opentelemetry-collector.config.service.pipelines.traces.receivers[0] | string | `"otlp"` | |
-| opentelemetry-collector.config.service.pipelines.traces.receivers[1] | string | `"zipkin"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[0] | string | `"datadog"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[1] | string | `"otlp"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[2] | string | `"zipkin"` | |
+| opentelemetry-collector.config.service.telemetry.metrics.address | string | `"[${env:MY_POD_IP}]:8888"` | |
| opentelemetry-collector.enabled | bool | `false` | |
| opentelemetry-collector.fullnameOverride | string | `"otel-collector"` | |
+| opentelemetry-collector.image.repository | string | `"otel/opentelemetry-collector-contrib"` | |
| opentelemetry-collector.mode | string | `"deployment"` | |
| prometheus.alertmanager.enabled | bool | `false` | |
| prometheus.enabled | bool | `true` | |
diff --git a/charts/gateway-addons-helm/dashboards/envoy-clusters.json b/charts/gateway-addons-helm/dashboards/envoy-clusters.json
index 4505f188e7d..8ee91675d96 100644
--- a/charts/gateway-addons-helm/dashboards/envoy-clusters.json
+++ b/charts/gateway-addons-helm/dashboards/envoy-clusters.json
@@ -259,7 +259,7 @@
"uid": "$datasource"
},
"editorMode": "builder",
- "expr": "SUM(envoy_server_memory_allocated{})",
+ "expr": "sum(envoy_server_memory_allocated{})",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "",
@@ -339,7 +339,7 @@
"uid": "$datasource"
},
"editorMode": "code",
- "expr": "SUM(envoy_server_memory_heap_size)",
+ "expr": "sum(envoy_server_memory_heap_size)",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "",
diff --git a/charts/gateway-addons-helm/dashboards/envoy-proxy-global.json b/charts/gateway-addons-helm/dashboards/envoy-proxy-global.json
index f2c0ae2b0d4..99522ae061e 100644
--- a/charts/gateway-addons-helm/dashboards/envoy-proxy-global.json
+++ b/charts/gateway-addons-helm/dashboards/envoy-proxy-global.json
@@ -1849,7 +1849,7 @@
"uid": "${datasource}"
},
"editorMode": "builder",
- "expr": "sum by(namespace) (rate(envoy_cluster_upstream_cx_rx_bytes_total{namespace=~\"$Namespace\"}[5m]))",
+ "expr": "sum by(namespace) (rate(envoy_cluster_upstream_cx_tx_bytes_total{namespace=~\"$Namespace\"}[5m]))",
"instant": false,
"legendFormat": "{{namespace}}",
"range": true,
diff --git a/charts/gateway-addons-helm/dashboards/global-ratelimit.json b/charts/gateway-addons-helm/dashboards/global-ratelimit.json
new file mode 100644
index 00000000000..3242aa62b7b
--- /dev/null
+++ b/charts/gateway-addons-helm/dashboards/global-ratelimit.json
@@ -0,0 +1,633 @@
+{
+ "annotations": {
+ "list": [
+ {
+ "builtIn": 1,
+ "datasource": {
+ "type": "grafana",
+ "uid": "-- Grafana --"
+ },
+ "enable": true,
+ "hide": true,
+ "iconColor": "rgba(0, 211, 255, 1)",
+ "name": "Annotations & Alerts",
+ "type": "dashboard"
+ }
+ ]
+ },
+ "description": "Envoy Gateway monitoring Dashboard with exported metrics.",
+ "editable": true,
+ "fiscalYearStartMonth": 0,
+ "graphTooltip": 0,
+ "id": 6,
+ "links": [],
+ "panels": [
+ {
+ "collapsed": false,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 0
+ },
+ "id": 273,
+ "panels": [],
+ "title": "Global Ratelimit",
+ "type": "row"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "description": "The fraction of this program's available CPU time used by the GC since the program started.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "series",
+ "axisGridShow": false,
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 25,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "miu"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 7,
+ "w": 8,
+ "x": 0,
+ "y": 1
+ },
+ "id": 274,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "hidden",
+ "placement": "right",
+ "showLegend": false
+ },
+ "tooltip": {
+ "maxHeight": 600,
+ "mode": "single",
+ "sort": "none"
+ }
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "disableTextWrap": false,
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "(go_memstats_gc_cpu_fraction)*1000000",
+ "format": "time_series",
+ "fullMetaSearch": false,
+ "includeNullMetadata": true,
+ "instant": false,
+ "legendFormat": "__auto",
+ "range": true,
+ "refId": "A",
+ "useBackend": false
+ }
+ ],
+ "title": "CPU Fraction",
+ "transparent": true,
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "description": "Resident memory size",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "decmbytes"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 7,
+ "w": 7,
+ "x": 9,
+ "y": 1
+ },
+ "id": 291,
+ "options": {
+ "minVizHeight": 75,
+ "minVizWidth": 75,
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showThresholdLabels": false,
+ "showThresholdMarkers": false,
+ "sizing": "auto"
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "disableTextWrap": false,
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "(process_resident_memory_bytes{app_kubernetes_io_component=\"ratelimit\"})/1000000",
+ "fullMetaSearch": false,
+ "includeNullMetadata": true,
+ "instant": false,
+ "legendFormat": "__auto",
+ "range": true,
+ "refId": "A",
+ "useBackend": false
+ }
+ ],
+ "title": "Resident Memory",
+ "transparent": true,
+ "type": "gauge"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "description": "Virtual memory size",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "min": 0,
+ "thresholds": {
+ "mode": "percentage",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "decmbytes"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 7,
+ "w": 7,
+ "x": 16,
+ "y": 1
+ },
+ "id": 325,
+ "options": {
+ "minVizHeight": 75,
+ "minVizWidth": 75,
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showThresholdLabels": false,
+ "showThresholdMarkers": false,
+ "sizing": "auto"
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "disableTextWrap": false,
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "(process_virtual_memory_bytes{app_kubernetes_io_component=\"ratelimit\"})/1000000",
+ "fullMetaSearch": false,
+ "includeNullMetadata": true,
+ "instant": false,
+ "legendFormat": "__auto",
+ "range": true,
+ "refId": "A",
+ "useBackend": false
+ }
+ ],
+ "title": "Virtual Memory",
+ "transparent": true,
+ "type": "gauge"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "description": "Number of ratelimit rule hits in total",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "fixedColor": "light-blue",
+ "mode": "shades"
+ },
+ "fieldMinMax": false,
+ "mappings": [],
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 0,
+ "y": 8
+ },
+ "id": 308,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "none",
+ "justifyMode": "center",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "value",
+ "wideLayout": false
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "disableTextWrap": false,
+ "editorMode": "builder",
+ "exemplar": false,
+ "expr": "ratelimit_service_rate_limit_total_hits{domain=\"$DefaultDomain\", key1=\"httproute/default/http-ratelimit/rule/0/match/0/ratelimit_example_httproute/default/http-ratelimit/rule/0/match/0/ratelimit_example\", key2=\"rule-0-match-0_rule-0-match-0\"}",
+ "fullMetaSearch": false,
+ "includeNullMetadata": true,
+ "instant": false,
+ "interval": "",
+ "legendFormat": "__auto",
+ "range": true,
+ "refId": "A",
+ "useBackend": false
+ }
+ ],
+ "title": "Total Hits",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "description": "Number of rule hits over the NearLimit ratio threshold (currently 80%) but under the threshold rate.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "fixedColor": "light-blue",
+ "mode": "shades"
+ },
+ "fieldMinMax": false,
+ "mappings": [],
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 6,
+ "y": 8
+ },
+ "id": 326,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "none",
+ "justifyMode": "center",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "value",
+ "wideLayout": false
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "disableTextWrap": false,
+ "editorMode": "builder",
+ "exemplar": false,
+ "expr": "ratelimit_service_rate_limit_near_limit{domain=\"$DefaultDomain\", key1=\"httproute/default/http-ratelimit/rule/0/match/0/ratelimit_example_httproute/default/http-ratelimit/rule/0/match/0/ratelimit_example\", key2=\"rule-0-match-0_rule-0-match-0\"}",
+ "fullMetaSearch": false,
+ "includeNullMetadata": true,
+ "instant": false,
+ "interval": "",
+ "legendFormat": "__auto",
+ "range": true,
+ "refId": "A",
+ "useBackend": false
+ }
+ ],
+ "title": "Near Limit",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "description": "Number of rule hits exceeding the threshold rate",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "fixedColor": "light-blue",
+ "mode": "shades"
+ },
+ "fieldMinMax": false,
+ "mappings": [],
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 12,
+ "y": 8
+ },
+ "id": 327,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "none",
+ "justifyMode": "center",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "value",
+ "wideLayout": false
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "disableTextWrap": false,
+ "editorMode": "builder",
+ "exemplar": false,
+ "expr": "ratelimit_service_rate_limit_over_limit{domain=\"$DefaultDomain\", key1=\"httproute/default/http-ratelimit/rule/0/match/0/ratelimit_example_httproute/default/http-ratelimit/rule/0/match/0/ratelimit_example\", key2=\"rule-0-match-0_rule-0-match-0\"}",
+ "fullMetaSearch": false,
+ "includeNullMetadata": true,
+ "instant": false,
+ "interval": "",
+ "legendFormat": "__auto",
+ "range": true,
+ "refId": "A",
+ "useBackend": false
+ }
+ ],
+ "title": "Over Limit",
+ "type": "stat"
+ }
+ ],
+ "refresh": "",
+ "schemaVersion": 39,
+ "tags": [
+ "Control Plane"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "selected": false,
+ "text": "Prometheus",
+ "value": "PBFA97CFB590B2093"
+ },
+ "hide": 0,
+ "includeAll": false,
+ "multi": false,
+ "name": "datasource",
+ "options": [],
+ "query": "prometheus",
+ "refresh": 1,
+ "regex": "",
+ "skipUrlSync": false,
+ "type": "datasource"
+ },
+ {
+ "allValue": ".*",
+ "current": {
+ "selected": false,
+ "text": "envoy-gateway-system",
+ "value": "envoy-gateway-system"
+ },
+ "datasource": {
+ "type": "prometheus",
+ "uid": "$datasource"
+ },
+ "definition": "label_values(watchable_depth,namespace)",
+ "hide": 0,
+ "includeAll": false,
+ "multi": false,
+ "name": "Namespace",
+ "options": [],
+ "query": {
+ "qryType": 1,
+ "query": "label_values(watchable_depth,namespace)",
+ "refId": "PrometheusVariableQueryEditor-VariableQuery"
+ },
+ "refresh": 1,
+ "regex": "",
+ "skipUrlSync": false,
+ "sort": 0,
+ "type": "query"
+ },
+ {
+ "allValue": ".*",
+ "current": {
+ "selected": true,
+ "text": [
+ "All"
+ ],
+ "value": [
+ "$__all"
+ ]
+ },
+ "datasource": {
+ "type": "prometheus",
+ "uid": "$datasource"
+ },
+ "definition": "label_values(watchable_depth,runner)",
+ "hide": 0,
+ "includeAll": true,
+ "multi": true,
+ "name": "Runner",
+ "options": [],
+ "query": {
+ "qryType": 1,
+ "query": "label_values(watchable_depth,runner)",
+ "refId": "PrometheusVariableQueryEditor-VariableQuery"
+ },
+ "refresh": 2,
+ "regex": "",
+ "skipUrlSync": false,
+ "sort": 0,
+ "type": "query"
+ },
+ {
+ "current": {
+ "selected": false,
+ "text": "default/eg/http",
+ "value": "default/eg/http"
+ },
+ "description": "DefaultDomain is set to default/eg/http",
+ "hide": 0,
+ "includeAll": false,
+ "multi": false,
+ "name": "DefaultDomain",
+ "options": [
+ {
+ "selected": true,
+ "text": "default/eg/http",
+ "value": "default/eg/http"
+ }
+ ],
+ "query": "default/eg/http",
+ "skipUrlSync": false,
+ "type": "custom"
+ }
+ ]
+ },
+ "time": {
+ "from": "now-6h",
+ "to": "now"
+ },
+ "timeRangeUpdatedDuringEditOrView": false,
+ "timepicker": {},
+ "timezone": "browser",
+ "title": "Global Ratelimit",
+ "uid": "R2xvYmFsIFJhdGVsaW1pdAo",
+ "version": 4,
+ "weekStart": ""
+}
\ No newline at end of file
diff --git a/charts/gateway-addons-helm/values.yaml b/charts/gateway-addons-helm/values.yaml
index fa98354c5f0..f8f80958129 100644
--- a/charts/gateway-addons-helm/values.yaml
+++ b/charts/gateway-addons-helm/values.yaml
@@ -10,6 +10,8 @@ grafana:
type: prometheus
url: http://prometheus
adminPassword: admin
+ testFramework:
+ enabled: false
service:
type: LoadBalancer
dashboardProviders:
@@ -58,6 +60,7 @@ prometheus:
# Values for Fluent-bit dependency
+# TODO: remove fluent-bit dependency
fluent-bit:
enabled: true
image:
@@ -165,6 +168,109 @@ loki:
gateway:
enabled: false
+# Values for Alloy dependency
+alloy:
+ enabled: false
+ fullnameOverride: alloy
+ alloy:
+ configMap:
+ content: |-
+ // Write your Alloy config here:
+ logging {
+ level = "info"
+ format = "logfmt"
+ }
+ loki.write "alloy" {
+ endpoint {
+ url = "http://loki.monitoring.svc:3100/loki/api/v1/push"
+ }
+ }
+ // discovery.kubernetes allows you to find scrape targets from Kubernetes resources.
+ // It watches cluster state and ensures targets are continually synced with what is currently running in your cluster.
+ discovery.kubernetes "pod" {
+ role = "pod"
+ }
+
+ // discovery.relabel rewrites the label set of the input targets by applying one or more relabeling rules.
+ // If no rules are defined, then the input targets are exported as-is.
+ discovery.relabel "pod_logs" {
+ targets = discovery.kubernetes.pod.targets
+
+ // Label creation - "namespace" field from "__meta_kubernetes_namespace"
+ rule {
+ source_labels = ["__meta_kubernetes_namespace"]
+ action = "replace"
+ target_label = "namespace"
+ }
+
+ // Label creation - "pod" field from "__meta_kubernetes_pod_name"
+ rule {
+ source_labels = ["__meta_kubernetes_pod_name"]
+ action = "replace"
+ target_label = "pod"
+ }
+
+ // Label creation - "container" field from "__meta_kubernetes_pod_container_name"
+ rule {
+ source_labels = ["__meta_kubernetes_pod_container_name"]
+ action = "replace"
+ target_label = "container"
+ }
+
+ // Label creation - "app" field from "__meta_kubernetes_pod_label_app_kubernetes_io_name"
+ rule {
+ source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_name"]
+ action = "replace"
+ target_label = "app"
+ }
+
+ // Label creation - "job" field from "__meta_kubernetes_namespace" and "__meta_kubernetes_pod_container_name"
+ // Concatenate values __meta_kubernetes_namespace/__meta_kubernetes_pod_container_name
+ rule {
+ source_labels = ["__meta_kubernetes_namespace", "__meta_kubernetes_pod_container_name"]
+ action = "replace"
+ target_label = "job"
+ separator = "/"
+ replacement = "$1"
+ }
+
+ // Label creation - "container" field from "__meta_kubernetes_pod_uid" and "__meta_kubernetes_pod_container_name"
+ // Concatenate values __meta_kubernetes_pod_uid/__meta_kubernetes_pod_container_name.log
+ rule {
+ source_labels = ["__meta_kubernetes_pod_uid", "__meta_kubernetes_pod_container_name"]
+ action = "replace"
+ target_label = "__path__"
+ separator = "/"
+ replacement = "/var/log/pods/*$1/*.log"
+ }
+
+ // Label creation - "container_runtime" field from "__meta_kubernetes_pod_container_id"
+ rule {
+ source_labels = ["__meta_kubernetes_pod_container_id"]
+ action = "replace"
+ target_label = "container_runtime"
+ regex = "^(\\S+):\\/\\/.+$"
+ replacement = "$1"
+ }
+ }
+
+ // loki.source.kubernetes tails logs from Kubernetes containers using the Kubernetes API.
+ loki.source.kubernetes "pod_logs" {
+ targets = discovery.relabel.pod_logs.output
+ forward_to = [loki.process.pod_logs.receiver]
+ }
+ // loki.process receives log entries from other Loki components, applies one or more processing stages,
+ // and forwards the results to the list of receivers in the component’s arguments.
+ loki.process "pod_logs" {
+ stage.static_labels {
+ values = {
+ cluster = "envoy-gateway",
+ }
+ }
+
+ forward_to = [loki.write.alloy.receiver]
+ }
+
# Values for Tempo dependency
tempo:
@@ -179,11 +285,13 @@ opentelemetry-collector:
enabled: false
fullnameOverride: otel-collector
mode: deployment
+ image:
+ repository: "otel/opentelemetry-collector-contrib"
config:
exporters:
prometheus:
- endpoint: 0.0.0.0:19001
- logging:
+ endpoint: "[${env:MY_POD_IP}]:19001"
+ debug:
verbosity: detailed
loki:
endpoint: "http://loki.monitoring.svc:3100/loki/api/v1/push"
@@ -192,10 +300,8 @@ opentelemetry-collector:
tls:
insecure: true
extensions:
- # The health_check extension is mandatory for this chart.
- # Without the health_check extension the collector will fail the readiness and liveliness probes.
- # The health_check extension can be modified, but should never be removed.
- health_check: {}
+ health_check:
+ endpoint: "[${env:MY_POD_IP}]:13133"
processors:
attributes:
actions:
@@ -205,15 +311,36 @@ opentelemetry-collector:
# Loki will convert this to k8s_pod_name label.
value: k8s.pod.name, k8s.namespace.name
receivers:
+ jaeger:
+ protocols:
+ grpc:
+ endpoint: "[${env:MY_POD_IP}]:14250"
+ thrift_http:
+ endpoint: "[${env:MY_POD_IP}]:14268"
+ thrift_compact:
+ endpoint: "[${env:MY_POD_IP}]:6831"
+ datadog:
+ endpoint: "[${env:MY_POD_IP}]:8126"
zipkin:
- endpoint: ${env:MY_POD_IP}:9411
+ endpoint: "[${env:MY_POD_IP}]:9411"
otlp:
protocols:
grpc:
- endpoint: ${env:MY_POD_IP}:4317
+ endpoint: "[${env:MY_POD_IP}]:4317"
http:
- endpoint: ${env:MY_POD_IP}:4318
+ endpoint: "[${env:MY_POD_IP}]:4318"
+ prometheus:
+ config:
+ scrape_configs:
+ - job_name: opentelemetry-collector
+ scrape_interval: 10s
+ static_configs:
+ - targets:
+ - "[${env:MY_POD_IP}]:8888"
service:
+ telemetry:
+ metrics:
+ address: "[${env:MY_POD_IP}]:8888"
extensions:
- health_check
pipelines:
@@ -221,6 +348,7 @@ opentelemetry-collector:
exporters:
- prometheus
receivers:
+ - datadog
- otlp
logs:
exporters:
@@ -233,5 +361,6 @@ opentelemetry-collector:
exporters:
- otlp
receivers:
+ - datadog
- otlp
- zipkin
diff --git a/charts/gateway-helm/README.md b/charts/gateway-helm/README.md
index da3f7572bd1..5d9cecf616b 100644
--- a/charts/gateway-helm/README.md
+++ b/charts/gateway-helm/README.md
@@ -59,7 +59,7 @@ To uninstall the chart:
| Key | Type | Default | Description |
|-----|------|---------|-------------|
-| certgen | object | `{"job":{"annotations":{},"resources":{},"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
+| certgen | object | `{"job":{"affinity":{},"annotations":{},"nodeSelector":{},"resources":{},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsGroup":65534,"runAsNonRoot":true,"runAsUser":65534,"seccompProfile":{"type":"RuntimeDefault"}},"tolerations":[],"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
| config.envoyGateway.gateway.controllerName | string | `"gateway.envoyproxy.io/gatewayclass-controller"` | |
| config.envoyGateway.logging.level.default | string | `"info"` | |
| config.envoyGateway.provider.type | string | `"Kubernetes"` | |
@@ -68,14 +68,21 @@ To uninstall the chart:
| deployment.envoyGateway.image.tag | string | `""` | |
| deployment.envoyGateway.imagePullPolicy | string | `""` | |
| deployment.envoyGateway.imagePullSecrets | list | `[]` | |
-| deployment.envoyGateway.resources.limits.cpu | string | `"500m"` | |
| deployment.envoyGateway.resources.limits.memory | string | `"1024Mi"` | |
| deployment.envoyGateway.resources.requests.cpu | string | `"100m"` | |
| deployment.envoyGateway.resources.requests.memory | string | `"256Mi"` | |
+| deployment.envoyGateway.securityContext.allowPrivilegeEscalation | bool | `false` | |
+| deployment.envoyGateway.securityContext.capabilities.drop[0] | string | `"ALL"` | |
+| deployment.envoyGateway.securityContext.privileged | bool | `false` | |
+| deployment.envoyGateway.securityContext.runAsGroup | int | `65532` | |
+| deployment.envoyGateway.securityContext.runAsNonRoot | bool | `true` | |
+| deployment.envoyGateway.securityContext.runAsUser | int | `65532` | |
+| deployment.envoyGateway.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | |
| deployment.pod.affinity | object | `{}` | |
| deployment.pod.annotations."prometheus.io/port" | string | `"19001"` | |
| deployment.pod.annotations."prometheus.io/scrape" | string | `"true"` | |
| deployment.pod.labels | object | `{}` | |
+| deployment.pod.nodeSelector | object | `{}` | |
| deployment.pod.tolerations | list | `[]` | |
| deployment.pod.topologySpreadConstraints | list | `[]` | |
| deployment.ports[0].name | string | `"grpc"` | |
@@ -90,6 +97,7 @@ To uninstall the chart:
| deployment.ports[3].name | string | `"metrics"` | |
| deployment.ports[3].port | int | `19001` | |
| deployment.ports[3].targetPort | int | `19001` | |
+| deployment.priorityClassName | string | `nil` | |
| deployment.replicas | int | `1` | |
| global.images.envoyGateway.image | string | `nil` | |
| global.images.envoyGateway.pullPolicy | string | `nil` | |
@@ -99,4 +107,5 @@ To uninstall the chart:
| global.images.ratelimit.pullSecrets | list | `[]` | |
| kubernetesClusterDomain | string | `"cluster.local"` | |
| podDisruptionBudget.minAvailable | int | `0` | |
+| service.annotations | object | `{}` | |
diff --git a/charts/gateway-helm/crds/gatewayapi-crds.yaml b/charts/gateway-helm/crds/gatewayapi-crds.yaml
index 8a50a1fa26a..f311060d1f3 100644
--- a/charts/gateway-helm/crds/gatewayapi-crds.yaml
+++ b/charts/gateway-helm/crds/gatewayapi-crds.yaml
@@ -23,10 +23,12 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
- gateway.networking.k8s.io/bundle-version: v1.1.0
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+ gateway.networking.k8s.io/bundle-version: v1.2.1
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
+ labels:
+ gateway.networking.k8s.io/policy: Direct
name: backendlbpolicies.gateway.networking.k8s.io
spec:
group: gateway.networking.k8s.io
@@ -77,7 +79,6 @@ spec:
SessionPersistence defines and configures session persistence
for the backend.
-
Support: Extended
properties:
absoluteTimeout:
@@ -86,7 +87,6 @@ spec:
session. Once the AbsoluteTimeout duration has elapsed, the
session becomes invalid.
-
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
@@ -95,7 +95,6 @@ spec:
CookieConfig provides configuration settings that are specific
to cookie-based session persistence.
-
Support: Core
properties:
lifetimeType:
@@ -107,20 +106,16 @@ spec:
attributes, while a session cookie is deleted when the current
session ends.
-
When set to "Permanent", AbsoluteTimeout indicates the
cookie's lifetime via the Expires or Max-Age cookie attributes
and is required.
-
When set to "Session", AbsoluteTimeout indicates the
absolute lifetime of the cookie tracked by the gateway and
is optional.
-
Support: Core for "Session" type
-
Support: Extended for "Permanent" type
enum:
- Permanent
@@ -133,7 +128,6 @@ spec:
Once the session has been idle for more than the specified
IdleTimeout duration, the session becomes invalid.
-
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
@@ -144,7 +138,6 @@ spec:
should avoid reusing session names to prevent unintended
consequences, such as rejection or unpredictable behavior.
-
Support: Implementation-specific
maxLength: 128
type: string
@@ -155,10 +148,8 @@ spec:
the use a header or cookie. Defaults to cookie based session
persistence.
-
Support: Core for "Cookie" type
-
Support: Extended for "Header" type
enum:
- Cookie
@@ -168,8 +159,8 @@ spec:
x-kubernetes-validations:
- message: AbsoluteTimeout must be specified when cookie lifetimeType
is Permanent
- rule: '!has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType
- != ''Permanent'' || has(self.absoluteTimeout)'
+ rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType)
+ || self.cookieConfig.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)'
targetRefs:
description: |-
TargetRef identifies an API object to apply policy to.
@@ -228,27 +219,22 @@ spec:
the controller first sees the policy and SHOULD update the entry as
appropriate when the relevant ancestor is modified.
-
Note that choosing the relevant ancestor is left to the Policy designers;
an important part of Policy design is designing the right object level at
which to namespace this status.
-
Note also that implementations MUST ONLY populate ancestor status for
the Ancestor resources they are responsible for. Implementations MUST
use the ControllerName field to uniquely identify the entries in this list
that they are responsible for.
-
Note that to achieve this, the list of PolicyAncestorStatus structs
MUST be treated as a map with a composite key, made up of the AncestorRef
and ControllerName fields combined.
-
A maximum of 16 ancestors will be represented in this list. An empty list
means the Policy is not relevant for any ancestors.
-
If this slice is full, implementations MUST NOT add further entries.
Instead they MUST consider the policy unimplementable and signal that
on any related resources such as the ancestor that would be referenced
@@ -260,7 +246,6 @@ spec:
PolicyAncestorStatus describes the status of a route with respect to an
associated Ancestor.
-
Ancestors refer to objects that are either the Target of a policy or above it
in terms of object hierarchy. For example, if a policy targets a Service, the
Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
@@ -269,28 +254,23 @@ spec:
SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
have a _very_ good reason otherwise.
-
In the context of policy attachment, the Ancestor is used to distinguish which
resource results in a distinct application of this policy. For example, if a policy
targets a Service, it may have a distinct result per attached Gateway.
-
Policies targeting the same resource may have different effects depending on the
ancestors of those resources. For example, different Gateways targeting the same
Service may have different capabilities, especially if they have different underlying
implementations.
-
For example, in BackendTLSPolicy, the Policy attaches to a Service that is
used as a backend in a HTTPRoute that is itself attached to a Gateway.
In this case, the relevant object for status is the Gateway, and that is the
ancestor object referred to in this status.
-
Note that a parent is also an ancestor, so for objects where the parent is the
relevant object for status, this struct SHOULD still be used.
-
This struct is intended to be used in a slice that's effectively a map,
with a composite key made up of the AncestorRef and the ControllerName.
properties:
@@ -307,7 +287,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -317,14 +296,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -334,7 +310,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -344,7 +319,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -352,12 +326,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -365,7 +337,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -376,7 +347,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -386,18 +356,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -406,7 +373,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -417,7 +383,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -425,12 +390,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -440,7 +403,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -453,18 +415,8 @@ spec:
description: Conditions describes the status of the Policy with
respect to the given Ancestor.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -506,12 +458,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -534,15 +481,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
@@ -580,8 +524,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
- gateway.networking.k8s.io/bundle-version: v1.1.0
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+ gateway.networking.k8s.io/bundle-version: v1.2.1
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
labels:
@@ -631,6 +575,29 @@ spec:
spec:
description: Spec defines the desired state of BackendTLSPolicy.
properties:
+ options:
+ additionalProperties:
+ description: |-
+ AnnotationValue is the value of an annotation in Gateway API. This is used
+ for validation of maps such as TLS options. This roughly matches Kubernetes
+ annotation validation, although the length validation in that case is based
+ on the entire size of the annotations struct.
+ maxLength: 4096
+ minLength: 0
+ type: string
+ description: |-
+ Options are a list of key/value pairs to enable extended TLS
+ configuration for each implementation. For example, configuring the
+ minimum TLS version or supported cipher suites.
+
+ A set of common keys MAY be defined by the API in the future. To avoid
+ any ambiguity, implementation-specific definitions MUST use
+ domain-prefixed names, such as `example.com/my-custom-option`.
+ Un-prefixed names are reserved for key names defined by Gateway API.
+
+ Support: Implementation-specific
+ maxProperties: 16
+ type: object
targetRefs:
description: |-
TargetRefs identifies an API object to apply the policy to.
@@ -640,10 +607,8 @@ spec:
by default, but this default may change in the future to provide
a more granular application of the policy.
-
Support: Extended for Kubernetes Service
-
Support: Implementation-specific for any other resource
items:
description: |-
@@ -653,7 +618,6 @@ spec:
mode works, and a sample Policy resource, refer to the policy attachment
documentation for Gateway API.
-
Note: This should only be used for direct policy attachment when references
to SectionName are actually needed. In all other cases,
LocalPolicyTargetReference should be used.
@@ -680,12 +644,10 @@ spec:
unspecified, this targetRef targets the entire resource. In the following
resources, SectionName is interpreted as the following:
-
* Gateway: Listener name
* HTTPRoute: HTTPRouteRule name
* Service: Port name
-
If a SectionName is specified, but does not exist on the targeted object,
the Policy must fail to attach, and the policy implementation should record
a `ResolvedRefs` or similar Condition in the Policy's status.
@@ -710,26 +672,21 @@ spec:
contain a PEM-encoded TLS CA certificate bundle, which is used to
validate a TLS handshake between the Gateway and backend Pod.
-
If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be
specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,
not both. If CACertifcateRefs is empty or unspecified, the configuration for
WellKnownCACertificates MUST be honored instead if supported by the implementation.
-
References to a resource in a different namespace are invalid for the
moment, although we will revisit this in the future.
-
A single CACertificateRef to a Kubernetes ConfigMap kind has "Core" support.
Implementations MAY choose to support attaching multiple certificates to
a backend, but this behavior is implementation-specific.
-
Support: Core - An optional single reference to a Kubernetes ConfigMap,
with the CA certificate in a key named `ca.crt`.
-
Support: Implementation-specific (More than one reference, or other kinds
of resources).
items:
@@ -739,7 +696,6 @@ spec:
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
-
References to objects with invalid Group and Kind are not valid, and must
be rejected by the implementation, with appropriate Conditions set
on the containing object.
@@ -775,23 +731,84 @@ spec:
Hostname is used for two purposes in the connection between Gateways and
backends:
-
1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066).
- 2. Hostname MUST be used for authentication and MUST match the certificate
- served by the matching backend.
-
+ 2. If SubjectAltNames is not specified, Hostname MUST be used for
+ authentication and MUST match the certificate served by the matching
+ backend.
Support: Core
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
+ subjectAltNames:
+ description: |-
+ SubjectAltNames contains one or more Subject Alternative Names.
+ When specified, the certificate served from the backend MUST have at least one
+ Subject Alternate Name matching one of the specified SubjectAltNames.
+
+ Support: Core
+ items:
+ description: SubjectAltName represents Subject Alternative Name.
+ properties:
+ hostname:
+ description: |-
+ Hostname contains Subject Alternative Name specified in DNS name format.
+ Required when Type is set to Hostname, ignored otherwise.
+
+ Support: Core
+ maxLength: 253
+ minLength: 1
+ pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ type:
+ description: |-
+ Type determines the format of the Subject Alternative Name. Always required.
+
+ Support: Core
+ enum:
+ - Hostname
+ - URI
+ type: string
+ uri:
+ description: |-
+ URI contains Subject Alternative Name specified in a full URI format.
+ It MUST include both a scheme (e.g., "http" or "ftp") and a scheme-specific-part.
+ Common values include SPIFFE IDs like "spiffe://mycluster.example.com/ns/myns/sa/svc1sa".
+ Required when Type is set to URI, ignored otherwise.
+
+ Support: Core
+ maxLength: 253
+ minLength: 1
+ pattern: ^(([^:/?#]+):)(//([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: SubjectAltName element must contain Hostname, if
+ Type is set to Hostname
+ rule: '!(self.type == "Hostname" && (!has(self.hostname) ||
+ self.hostname == ""))'
+ - message: SubjectAltName element must not contain Hostname,
+ if Type is not set to Hostname
+ rule: '!(self.type != "Hostname" && has(self.hostname) &&
+ self.hostname != "")'
+ - message: SubjectAltName element must contain URI, if Type
+ is set to URI
+ rule: '!(self.type == "URI" && (!has(self.uri) || self.uri
+ == ""))'
+ - message: SubjectAltName element must not contain URI, if Type
+ is not set to URI
+ rule: '!(self.type != "URI" && has(self.uri) && self.uri !=
+ "")'
+ maxItems: 5
+ type: array
wellKnownCACertificates:
description: |-
WellKnownCACertificates specifies whether system CA certificates may be used in
the TLS handshake between the gateway and backend pod.
-
If WellKnownCACertificates is unspecified or empty (""), then CACertificateRefs
must be specified with at least one entry for a valid configuration. Only one of
CACertificateRefs or WellKnownCACertificates may be specified, not both. If an
@@ -799,7 +816,6 @@ spec:
supplied is not supported, the Status Conditions on the Policy MUST be
updated to include an Accepted: False Condition with Reason: Invalid.
-
Support: Implementation-specific
enum:
- System
@@ -832,27 +848,22 @@ spec:
the controller first sees the policy and SHOULD update the entry as
appropriate when the relevant ancestor is modified.
-
Note that choosing the relevant ancestor is left to the Policy designers;
an important part of Policy design is designing the right object level at
which to namespace this status.
-
Note also that implementations MUST ONLY populate ancestor status for
the Ancestor resources they are responsible for. Implementations MUST
use the ControllerName field to uniquely identify the entries in this list
that they are responsible for.
-
Note that to achieve this, the list of PolicyAncestorStatus structs
MUST be treated as a map with a composite key, made up of the AncestorRef
and ControllerName fields combined.
-
A maximum of 16 ancestors will be represented in this list. An empty list
means the Policy is not relevant for any ancestors.
-
If this slice is full, implementations MUST NOT add further entries.
Instead they MUST consider the policy unimplementable and signal that
on any related resources such as the ancestor that would be referenced
@@ -864,7 +875,6 @@ spec:
PolicyAncestorStatus describes the status of a route with respect to an
associated Ancestor.
-
Ancestors refer to objects that are either the Target of a policy or above it
in terms of object hierarchy. For example, if a policy targets a Service, the
Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
@@ -873,28 +883,23 @@ spec:
SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
have a _very_ good reason otherwise.
-
In the context of policy attachment, the Ancestor is used to distinguish which
resource results in a distinct application of this policy. For example, if a policy
targets a Service, it may have a distinct result per attached Gateway.
-
Policies targeting the same resource may have different effects depending on the
ancestors of those resources. For example, different Gateways targeting the same
Service may have different capabilities, especially if they have different underlying
implementations.
-
For example, in BackendTLSPolicy, the Policy attaches to a Service that is
used as a backend in a HTTPRoute that is itself attached to a Gateway.
In this case, the relevant object for status is the Gateway, and that is the
ancestor object referred to in this status.
-
Note that a parent is also an ancestor, so for objects where the parent is the
relevant object for status, this struct SHOULD still be used.
-
This struct is intended to be used in a slice that's effectively a map,
with a composite key made up of the AncestorRef and the ControllerName.
properties:
@@ -911,7 +916,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -921,14 +925,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -938,7 +939,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -948,7 +948,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -956,12 +955,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -969,7 +966,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -980,7 +976,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -990,18 +985,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -1010,7 +1002,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -1021,7 +1012,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -1029,12 +1019,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -1044,7 +1032,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -1057,18 +1044,8 @@ spec:
description: Conditions describes the status of the Policy with
respect to the given Ancestor.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -1110,12 +1087,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -1138,15 +1110,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
@@ -1184,8 +1153,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
- gateway.networking.k8s.io/bundle-version: v1.1.0
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+ gateway.networking.k8s.io/bundle-version: v1.2.1
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: gatewayclasses.gateway.networking.k8s.io
@@ -1223,7 +1192,6 @@ spec:
GatewayClass describes a class of Gateways available to the user for creating
Gateway resources.
-
It is recommended that this resource be used as a template for Gateways. This
means that a Gateway is based on the state of the GatewayClass at the time it
was created and changes to the GatewayClass or associated parameters are not
@@ -1232,13 +1200,11 @@ spec:
If implementations choose to propagate GatewayClass changes to existing
Gateways, that MUST be clearly documented by the implementation.
-
Whenever one or more Gateways are using a GatewayClass, implementations SHOULD
add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the
associated GatewayClass. This ensures that a GatewayClass associated with a
Gateway is not deleted while in use.
-
GatewayClass is a Cluster level resource.
properties:
apiVersion:
@@ -1266,13 +1232,10 @@ spec:
ControllerName is the name of the controller that is managing Gateways of
this class. The value of this field MUST be a domain prefixed path.
-
Example: "example.net/gateway-controller".
-
This field is not mutable and cannot be empty.
-
Support: Core
maxLength: 253
minLength: 1
@@ -1291,21 +1254,19 @@ spec:
parameters corresponding to the GatewayClass. This is optional if the
controller does not require any additional configuration.
-
ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap,
or an implementation-specific custom resource. The resource can be
cluster-scoped or namespace-scoped.
-
- If the referent cannot be found, the GatewayClass's "InvalidParameters"
- status condition will be true.
-
+ If the referent cannot be found, refers to an unsupported kind, or when
+ the data within that resource is malformed, the GatewayClass SHOULD be
+ rejected with the "Accepted" status condition set to "False" and an
+ "InvalidParameters" reason.
A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified,
the merging behavior is implementation specific.
It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.
-
Support: Implementation-specific
properties:
group:
@@ -1346,13 +1307,12 @@ spec:
conditions:
- lastTransitionTime: "1970-01-01T00:00:00Z"
message: Waiting for controller
- reason: Waiting
+ reason: Pending
status: Unknown
type: Accepted
description: |-
Status defines the current state of GatewayClass.
-
Implementations MUST populate status on all GatewayClass resources which
specify their controller name.
properties:
@@ -1367,20 +1327,11 @@ spec:
Conditions is the current status from the controller for
this GatewayClass.
-
Controllers should prefer to publish conditions using values
of GatewayClassConditionType for the type of each Condition.
items:
- description: "Condition contains details for one aspect of the current
- state of this API Resource.\n---\nThis struct is intended for
- direct use as an array at the field path .status.conditions. For
- example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
- observations of a foo's current state.\n\t // Known .status.conditions.type
- are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
- \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
- patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of the current
+ state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -1421,12 +1372,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -1445,15 +1391,22 @@ spec:
supportedFeatures:
description: |
SupportedFeatures is the set of features the GatewayClass support.
- It MUST be sorted in ascending alphabetical order.
+ It MUST be sorted in ascending alphabetical order by the Name key.
items:
- description: |-
- SupportedFeature is used to describe distinct features that are covered by
- conformance tests.
- type: string
+ properties:
+ name:
+ description: |-
+ FeatureName is used to describe distinct features that are covered by
+ conformance tests.
+ type: string
+ required:
+ - name
+ type: object
maxItems: 64
type: array
- x-kubernetes-list-type: set
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
type: object
required:
- spec
@@ -1483,7 +1436,6 @@ spec:
GatewayClass describes a class of Gateways available to the user for creating
Gateway resources.
-
It is recommended that this resource be used as a template for Gateways. This
means that a Gateway is based on the state of the GatewayClass at the time it
was created and changes to the GatewayClass or associated parameters are not
@@ -1492,13 +1444,11 @@ spec:
If implementations choose to propagate GatewayClass changes to existing
Gateways, that MUST be clearly documented by the implementation.
-
Whenever one or more Gateways are using a GatewayClass, implementations SHOULD
add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the
associated GatewayClass. This ensures that a GatewayClass associated with a
Gateway is not deleted while in use.
-
GatewayClass is a Cluster level resource.
properties:
apiVersion:
@@ -1526,13 +1476,10 @@ spec:
ControllerName is the name of the controller that is managing Gateways of
this class. The value of this field MUST be a domain prefixed path.
-
Example: "example.net/gateway-controller".
-
This field is not mutable and cannot be empty.
-
Support: Core
maxLength: 253
minLength: 1
@@ -1551,21 +1498,19 @@ spec:
parameters corresponding to the GatewayClass. This is optional if the
controller does not require any additional configuration.
-
ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap,
or an implementation-specific custom resource. The resource can be
cluster-scoped or namespace-scoped.
-
- If the referent cannot be found, the GatewayClass's "InvalidParameters"
- status condition will be true.
-
+ If the referent cannot be found, refers to an unsupported kind, or when
+ the data within that resource is malformed, the GatewayClass SHOULD be
+ rejected with the "Accepted" status condition set to "False" and an
+ "InvalidParameters" reason.
A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified,
the merging behavior is implementation specific.
It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.
-
Support: Implementation-specific
properties:
group:
@@ -1606,13 +1551,12 @@ spec:
conditions:
- lastTransitionTime: "1970-01-01T00:00:00Z"
message: Waiting for controller
- reason: Waiting
+ reason: Pending
status: Unknown
type: Accepted
description: |-
Status defines the current state of GatewayClass.
-
Implementations MUST populate status on all GatewayClass resources which
specify their controller name.
properties:
@@ -1627,20 +1571,11 @@ spec:
Conditions is the current status from the controller for
this GatewayClass.
-
Controllers should prefer to publish conditions using values
of GatewayClassConditionType for the type of each Condition.
items:
- description: "Condition contains details for one aspect of the current
- state of this API Resource.\n---\nThis struct is intended for
- direct use as an array at the field path .status.conditions. For
- example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
- observations of a foo's current state.\n\t // Known .status.conditions.type
- are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
- \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
- patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of the current
+ state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -1681,12 +1616,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -1705,15 +1635,22 @@ spec:
supportedFeatures:
description: |
SupportedFeatures is the set of features the GatewayClass support.
- It MUST be sorted in ascending alphabetical order.
+ It MUST be sorted in ascending alphabetical order by the Name key.
items:
- description: |-
- SupportedFeature is used to describe distinct features that are covered by
- conformance tests.
- type: string
+ properties:
+ name:
+ description: |-
+ FeatureName is used to describe distinct features that are covered by
+ conformance tests.
+ type: string
+ required:
+ - name
+ type: object
maxItems: 64
type: array
- x-kubernetes-list-type: set
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
type: object
required:
- spec
@@ -1736,8 +1673,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
- gateway.networking.k8s.io/bundle-version: v1.1.0
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+ gateway.networking.k8s.io/bundle-version: v1.2.1
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: gateways.gateway.networking.k8s.io
@@ -1801,27 +1738,22 @@ spec:
requested address is invalid or unavailable, the implementation MUST
indicate this in the associated entry in GatewayStatus.Addresses.
-
The Addresses field represents a request for the address(es) on the
"outside of the Gateway", that traffic bound for this Gateway will use.
This could be the IP address or hostname of an external load balancer or
other networking infrastructure, or some other address that traffic will
be sent to.
-
If no Addresses are specified, the implementation MAY schedule the
Gateway in an implementation-specific manner, assigning an appropriate
set of Addresses.
-
The implementation MUST bind all Listeners to every GatewayAddress that
it assigns to the Gateway and add a corresponding entry in
GatewayStatus.Addresses.
-
Support: Extended
-
items:
description: GatewayAddress describes an address that can be bound
to a Gateway.
@@ -1852,7 +1784,6 @@ spec:
Value of the address. The validity of the values will depend
on the type and support by the controller.
-
Examples: `1.2.3.4`, `128::1`, `my-ip-address`.
maxLength: 253
minLength: 1
@@ -1874,6 +1805,72 @@ spec:
- message: Hostname values must be unique
rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2,
a2.type == a1.type && a2.value == a1.value) : true )'
+ backendTLS:
+ description: |+
+ BackendTLS configures TLS settings for when this Gateway is connecting to
+ backends with TLS.
+
+ Support: Core
+
+ properties:
+ clientCertificateRef:
+ description: |+
+ ClientCertificateRef is a reference to an object that contains a Client
+ Certificate and the associated private key.
+
+ References to a resource in different namespace are invalid UNLESS there
+ is a ReferenceGrant in the target namespace that allows the certificate
+ to be attached. If a ReferenceGrant does not allow this reference, the
+ "ResolvedRefs" condition MUST be set to False for this listener with the
+ "RefNotPermitted" reason.
+
+ ClientCertificateRef can reference to standard Kubernetes resources, i.e.
+ Secret, or implementation-specific custom resources.
+
+ This setting can be overridden on the service level by use of BackendTLSPolicy.
+
+ Support: Core
+
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Secret
+ description: Kind is kind of the referent. For example "Secret".
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the referenced object. When unspecified, the local
+ namespace is inferred.
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ required:
+ - name
+ type: object
+ type: object
gatewayClassName:
description: |-
GatewayClassName used for this Gateway. This is the name of a
@@ -1882,13 +1879,10 @@ spec:
minLength: 1
type: string
infrastructure:
- description: |+
+ description: |-
Infrastructure defines infrastructure level attributes about this Gateway instance.
-
- Support: Core
-
-
+ Support: Extended
properties:
annotations:
additionalProperties:
@@ -1903,56 +1897,74 @@ spec:
description: |-
Annotations that SHOULD be applied to any resources created in response to this Gateway.
-
For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources.
For other implementations, this refers to any relevant (implementation specific) "annotations" concepts.
-
An implementation may chose to add additional implementation-specific annotations as they see fit.
-
Support: Extended
maxProperties: 8
type: object
+ x-kubernetes-validations:
+ - message: Annotation keys must be in the form of an optional
+ DNS subdomain prefix followed by a required name segment of
+ up to 63 characters.
+ rule: self.all(key, key.matches(r"""^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$"""))
+ - message: If specified, the annotation key's prefix must be a
+ DNS subdomain not longer than 253 characters in total.
+ rule: self.all(key, key.split("/")[0].size() < 253)
labels:
additionalProperties:
description: |-
- AnnotationValue is the value of an annotation in Gateway API. This is used
- for validation of maps such as TLS options. This roughly matches Kubernetes
- annotation validation, although the length validation in that case is based
- on the entire size of the annotations struct.
- maxLength: 4096
+ LabelValue is the value of a label in the Gateway API. This is used for validation
+ of maps such as Gateway infrastructure labels. This matches the Kubernetes
+ label validation rules:
+ * must be 63 characters or less (can be empty),
+ * unless empty, must begin and end with an alphanumeric character ([a-z0-9A-Z]),
+ * could contain dashes (-), underscores (_), dots (.), and alphanumerics between.
+
+ Valid values include:
+
+ * MyValue
+ * my.name
+ * 123-my-value
+ maxLength: 63
minLength: 0
+ pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$
type: string
description: |-
Labels that SHOULD be applied to any resources created in response to this Gateway.
-
For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources.
For other implementations, this refers to any relevant (implementation specific) "labels" concepts.
-
An implementation may chose to add additional implementation-specific labels as they see fit.
+ If an implementation maps these labels to Pods, or any other resource that would need to be recreated when labels
+ change, it SHOULD clearly warn about this behavior in documentation.
Support: Extended
maxProperties: 8
type: object
+ x-kubernetes-validations:
+ - message: Label keys must be in the form of an optional DNS subdomain
+ prefix followed by a required name segment of up to 63 characters.
+ rule: self.all(key, key.matches(r"""^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$"""))
+ - message: If specified, the label key's prefix must be a DNS
+ subdomain not longer than 253 characters in total.
+ rule: self.all(key, key.split("/")[0].size() < 253)
parametersRef:
description: |-
ParametersRef is a reference to a resource that contains the configuration
parameters corresponding to the Gateway. This is optional if the
controller does not require any additional configuration.
-
This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis
-
The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified,
the merging behavior is implementation specific.
It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.
-
Support: Implementation-specific
properties:
group:
@@ -1983,7 +1995,6 @@ spec:
logical endpoints that are bound on this Gateway's addresses.
At least one Listener MUST be specified.
-
Each Listener in a set of Listeners (for example, in a single Gateway)
MUST be _distinct_, in that a traffic flow MUST be able to be assigned to
exactly one listener. (This section uses "set of Listeners" rather than
@@ -1991,42 +2002,32 @@ spec:
from multiple Gateways onto a single data plane, and these rules _also_
apply in that case).
-
Practically, this means that each listener in a set MUST have a unique
combination of Port, Protocol, and, if supported by the protocol, Hostname.
-
Some combinations of port, protocol, and TLS settings are considered
Core support and MUST be supported by implementations based on their
targeted conformance profile:
-
HTTP Profile
-
1. HTTPRoute, Port: 80, Protocol: HTTP
2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided
-
TLS Profile
-
1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough
-
"Distinct" Listeners have the following property:
-
The implementation can match inbound requests to a single distinct
Listener. When multiple Listeners share values for fields (for
example, two Listeners with the same Port value), the implementation
can match requests to only one of the Listeners using other
Listener fields.
-
For example, the following Listener scenarios are distinct:
-
1. Multiple Listeners with the same Port that all use the "HTTP"
Protocol that all have unique Hostname values.
2. Multiple Listeners with the same Port that use either the "HTTPS" or
@@ -2034,45 +2035,37 @@ spec:
3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener
with the same Protocol has the same Port value.
-
Some fields in the Listener struct have possible values that affect
whether the Listener is distinct. Hostname is particularly relevant
for HTTP or HTTPS protocols.
-
When using the Hostname value to select between same-Port, same-Protocol
Listeners, the Hostname value must be different on each Listener for the
Listener to be distinct.
-
When the Listeners are distinct based on Hostname, inbound request
hostnames MUST match from the most specific to least specific Hostname
values to choose the correct Listener and its associated set of Routes.
-
Exact matches must be processed before wildcard matches, and wildcard
matches must be processed before fallback (empty Hostname value)
matches. For example, `"foo.example.com"` takes precedence over
`"*.example.com"`, and `"*.example.com"` takes precedence over `""`.
-
Additionally, if there are multiple wildcard entries, more specific
wildcard entries must be processed before less specific wildcard entries.
For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`.
The precise definition here is that the higher the number of dots in the
hostname to the right of the wildcard character, the higher the precedence.
-
The wildcard character will match any number of characters _and dots_ to
the left, however, so `"*.example.com"` will match both
`"foo.bar.example.com"` _and_ `"bar.example.com"`.
-
If a set of Listeners contains Listeners that are not distinct, then those
Listeners are Conflicted, and the implementation MUST set the "Conflicted"
condition in the Listener Status to "True".
-
Implementations MAY choose to accept a Gateway with some Conflicted
Listeners only if they only accept the partial Listener set that contains
no Conflicted Listeners. To put this another way, implementations may
@@ -2082,7 +2075,6 @@ spec:
Listener in this case, otherwise it violates the requirement that at
least one Listener must be present.
-
The implementation MUST set a "ListenersNotValid" condition on the
Gateway Status when the Gateway contains Conflicted Listeners whether or
not they accept the Gateway. That Condition SHOULD clearly
@@ -2090,26 +2082,21 @@ spec:
Accepted. Additionally, the Listener status for those listeners SHOULD
indicate which Listeners are conflicted and not Accepted.
-
A Gateway's Listeners are considered "compatible" if:
-
1. They are distinct.
2. The implementation can serve them in compliance with the Addresses
requirement that all Listeners are available on all assigned
addresses.
-
Compatible combinations in Extended support are expected to vary across
implementations. A combination that is compatible for one implementation
may not be compatible for another.
-
For example, an implementation that cannot serve both TCP and UDP listeners
on the same address, or cannot mix HTTPS and generic TLS listens on the same port
would not consider those cases compatible, even though they are distinct.
-
Note that requests SHOULD match at most one Listener. For example, if
Listeners are defined for "foo.example.com" and "*.example.com", a
request to "foo.example.com" SHOULD only be routed using routes attached
@@ -2117,11 +2104,9 @@ spec:
This concept is known as "Listener Isolation". Implementations that do
not support Listener Isolation MUST clearly document this.
-
Implementations MAY merge separate Gateways onto a single set of
Addresses if all Listeners across all Gateways are compatible.
-
Support: Core
items:
description: |-
@@ -2137,12 +2122,10 @@ spec:
Listener and the trusted namespaces where those Route resources MAY be
present.
-
Although a client request may match multiple route rules, only one rule
may ultimately receive the request. Matching precedence MUST be
determined in order of the following criteria:
-
* The most specific match as defined by the Route type.
* The oldest Route based on creation timestamp. For example, a Route with
a creation timestamp of "2020-09-08 01:02:03" is given precedence over
@@ -2151,7 +2134,6 @@ spec:
alphabetical order (namespace/name) should be given precedence. For
example, foo/bar is given precedence over foo/baz.
-
All valid rules within a Route attached to this Listener should be
implemented. Invalid Route rules can be ignored (sometimes that will mean
the full Route). If a Route rule transitions from valid to invalid,
@@ -2159,7 +2141,6 @@ spec:
example, even if a filter specified by a Route rule is invalid, the rest
of the rules within that Route should still be supported.
-
Support: Core
properties:
kinds:
@@ -2168,14 +2149,12 @@ spec:
to this Gateway Listener. When unspecified or empty, the kinds of Routes
selected are determined using the Listener protocol.
-
A RouteGroupKind MUST correspond to kinds of Routes that are compatible
with the application protocol specified in the Listener's Protocol field.
If an implementation does not support or recognize this resource type, it
MUST set the "ResolvedRefs" condition to False for this Listener with the
"InvalidRouteKinds" reason.
-
Support: Core
items:
description: RouteGroupKind indicates the group and kind
@@ -2205,7 +2184,6 @@ spec:
Namespaces indicates namespaces from which Routes may be attached to this
Listener. This is restricted to the namespace of this Gateway by default.
-
Support: Core
properties:
from:
@@ -2214,13 +2192,11 @@ spec:
From indicates where Routes will be selected for this Gateway. Possible
values are:
-
* All: Routes in all namespaces may be used by this Gateway.
* Selector: Routes in namespaces selected by the selector may be used by
this Gateway.
* Same: Only Routes in the same namespace may be used by this Gateway.
-
Support: Core
enum:
- All
@@ -2233,7 +2209,6 @@ spec:
only Routes in Namespaces matching this Selector will be selected by this
Gateway. This field is ignored for other values of "From".
-
Support: Core
properties:
matchExpressions:
@@ -2288,11 +2263,9 @@ spec:
field is ignored for protocols that don't require hostname based
matching.
-
Implementations MUST apply Hostname matching appropriately for each of
the following protocols:
-
* TLS: The Listener Hostname MUST match the SNI.
* HTTP: The Listener Hostname MUST match the Host header of the request.
* HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP
@@ -2300,19 +2273,16 @@ spec:
ensure that both the SNI and Host header match the Listener hostname,
it MUST clearly document that.
-
For HTTPRoute and TLSRoute resources, there is an interaction with the
`spec.hostnames` array. When both listener and route specify hostnames,
there MUST be an intersection between the values for a Route to be
accepted. For more information, refer to the Route specific Hostnames
documentation.
-
Hostnames that are prefixed with a wildcard label (`*.`) are interpreted
as a suffix match. That means that a match for `*.example.com` would match
both `test.example.com`, and `foo.test.example.com`, but not `example.com`.
-
Support: Core
maxLength: 253
minLength: 1
@@ -2323,7 +2293,6 @@ spec:
Name is the name of the Listener. This name MUST be unique within a
Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -2334,7 +2303,6 @@ spec:
Port is the network port. Multiple listeners may use the
same port, subject to the Listener compatibility rules.
-
Support: Core
format: int32
maximum: 65535
@@ -2344,11 +2312,10 @@ spec:
description: |-
Protocol specifies the network protocol this listener expects to receive.
-
Support: Core
maxLength: 255
minLength: 1
- pattern: ^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$
+ pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$
type: string
tls:
description: |-
@@ -2356,15 +2323,12 @@ spec:
the Protocol field is "HTTPS" or "TLS". It is invalid to set this field
if the Protocol field is "HTTP", "TCP", or "UDP".
-
The association of SNIs to Certificate defined in GatewayTLSConfig is
defined based on the Hostname field for this listener.
-
The GatewayClass MUST use the longest matching SNI out of all
available certificates for any TLS handshake.
-
Support: Core
properties:
certificateRefs:
@@ -2374,41 +2338,33 @@ spec:
establish a TLS handshake for requests that match the hostname of the
associated listener.
-
A single CertificateRef to a Kubernetes Secret has "Core" support.
Implementations MAY choose to support attaching multiple certificates to
a Listener, but this behavior is implementation-specific.
-
References to a resource in different namespace are invalid UNLESS there
is a ReferenceGrant in the target namespace that allows the certificate
to be attached. If a ReferenceGrant does not allow this reference, the
"ResolvedRefs" condition MUST be set to False for this listener with the
"RefNotPermitted" reason.
-
This field is required to have at least one element when the mode is set
to "Terminate" (default) and is optional otherwise.
-
CertificateRefs can reference to standard Kubernetes resources, i.e.
Secret, or implementation-specific custom resources.
-
Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls
-
Support: Implementation-specific (More than one reference or other resource types)
items:
description: |-
SecretObjectReference identifies an API object including its namespace,
defaulting to Secret.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
-
References to objects with invalid Group and Kind are not valid, and must
be rejected by the implementation, with appropriate Conditions set
on the containing object.
@@ -2439,13 +2395,11 @@ spec:
Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -2464,10 +2418,8 @@ spec:
that requests a user to specify the client certificate.
The maximum depth of a certificate chain accepted in verification is Implementation specific.
-
Support: Extended
-
properties:
caCertificateRefs:
description: |-
@@ -2476,21 +2428,17 @@ spec:
the Certificate Authorities that can be used
as a trust anchor to validate the certificates presented by the client.
-
A single CA certificate reference to a Kubernetes ConfigMap
has "Core" support.
Implementations MAY choose to support attaching multiple CA certificates to
a Listener, but this behavior is implementation-specific.
-
Support: Core - A single reference to a Kubernetes ConfigMap
with the CA certificate in a key named `ca.crt`.
-
Support: Implementation-specific (More than one reference, or other kinds
of resources).
-
References to a resource in a different namespace are invalid UNLESS there
is a ReferenceGrant in the target namespace that allows the certificate
to be attached. If a ReferenceGrant does not allow this reference, the
@@ -2500,11 +2448,9 @@ spec:
description: |-
ObjectReference identifies an API object including its namespace.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
-
References to objects with invalid Group and Kind are not valid, and must
be rejected by the implementation, with appropriate Conditions set
on the containing object.
@@ -2533,13 +2479,11 @@ spec:
Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -2560,7 +2504,6 @@ spec:
Mode defines the TLS behavior for the TLS session initiated by the client.
There are two possible modes:
-
- Terminate: The TLS session between the downstream client and the
Gateway is terminated at the Gateway. This mode requires certificates
to be specified in some way, such as populating the certificateRefs
@@ -2570,7 +2513,6 @@ spec:
the ClientHello message of the TLS protocol. The certificateRefs field
is ignored in this mode.
-
Support: Core
enum:
- Terminate
@@ -2591,13 +2533,11 @@ spec:
configuration for each implementation. For example, configuring the
minimum TLS version or supported cipher suites.
-
A set of common keys MAY be defined by the API in the future. To avoid
any ambiguity, implementation-specific definitions MUST use
domain-prefixed names, such as `example.com/my-custom-option`.
Un-prefixed names are reserved for key names defined by Gateway API.
-
Support: Implementation-specific
maxProperties: 16
type: object
@@ -2660,16 +2600,13 @@ spec:
Addresses lists the network addresses that have been bound to the
Gateway.
-
This list may differ from the addresses provided in the spec under some
conditions:
-
* no addresses are specified, all addresses are dynamically assigned
* a combination of specified and dynamic addresses are assigned
* a specified address was unusable (e.g. already in use)
-
items:
description: GatewayStatusAddress describes a network address that
is bound to a Gateway.
@@ -2700,7 +2637,6 @@ spec:
Value of the address. The validity of the values will depend
on the type and support by the controller.
-
Examples: `1.2.3.4`, `128::1`, `my-ip-address`.
maxLength: 253
minLength: 1
@@ -2730,30 +2666,19 @@ spec:
description: |-
Conditions describe the current conditions of the Gateway.
-
Implementations should prefer to express Gateway conditions
using the `GatewayConditionType` and `GatewayConditionReason`
constants so that operators and tools can converge on a common
vocabulary to describe Gateway state.
-
Known condition types are:
-
* "Accepted"
* "Programmed"
* "Ready"
items:
- description: "Condition contains details for one aspect of the current
- state of this API Resource.\n---\nThis struct is intended for
- direct use as an array at the field path .status.conditions. For
- example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
- observations of a foo's current state.\n\t // Known .status.conditions.type
- are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
- \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
- patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of the current
+ state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -2794,12 +2719,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -2826,7 +2746,6 @@ spec:
AttachedRoutes represents the total number of Routes that have been
successfully attached to this Listener.
-
Successful attachment of a Route to a Listener is based solely on the
combination of the AllowedRoutes field on the corresponding Listener
and the Route's ParentRefs field. A Route is successfully attached to
@@ -2839,7 +2758,6 @@ spec:
for Listeners with condition Accepted: false and MUST count successfully
attached Routes that may themselves have Accepted: false conditions.
-
Uses for this field include troubleshooting Route attachment and
measuring blast radius/impact of changes to a Listener.
format: int32
@@ -2848,18 +2766,8 @@ spec:
description: Conditions describe the current condition of this
listener.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -2901,12 +2809,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -2935,7 +2838,6 @@ spec:
listener. This MUST represent the kinds an implementation supports for
that Listener configuration.
-
If kinds are specified in Spec that are not supported, they MUST NOT
appear in this list and an implementation MUST set the "ResolvedRefs"
condition to "False" with the "InvalidRouteKinds" reason. If both valid
@@ -3028,27 +2930,22 @@ spec:
requested address is invalid or unavailable, the implementation MUST
indicate this in the associated entry in GatewayStatus.Addresses.
-
The Addresses field represents a request for the address(es) on the
"outside of the Gateway", that traffic bound for this Gateway will use.
This could be the IP address or hostname of an external load balancer or
other networking infrastructure, or some other address that traffic will
be sent to.
-
If no Addresses are specified, the implementation MAY schedule the
Gateway in an implementation-specific manner, assigning an appropriate
set of Addresses.
-
The implementation MUST bind all Listeners to every GatewayAddress that
it assigns to the Gateway and add a corresponding entry in
GatewayStatus.Addresses.
-
Support: Extended
-
items:
description: GatewayAddress describes an address that can be bound
to a Gateway.
@@ -3079,7 +2976,6 @@ spec:
Value of the address. The validity of the values will depend
on the type and support by the controller.
-
Examples: `1.2.3.4`, `128::1`, `my-ip-address`.
maxLength: 253
minLength: 1
@@ -3101,6 +2997,72 @@ spec:
- message: Hostname values must be unique
rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2,
a2.type == a1.type && a2.value == a1.value) : true )'
+ backendTLS:
+ description: |+
+ BackendTLS configures TLS settings for when this Gateway is connecting to
+ backends with TLS.
+
+ Support: Core
+
+ properties:
+ clientCertificateRef:
+ description: |+
+ ClientCertificateRef is a reference to an object that contains a Client
+ Certificate and the associated private key.
+
+ References to a resource in different namespace are invalid UNLESS there
+ is a ReferenceGrant in the target namespace that allows the certificate
+ to be attached. If a ReferenceGrant does not allow this reference, the
+ "ResolvedRefs" condition MUST be set to False for this listener with the
+ "RefNotPermitted" reason.
+
+ ClientCertificateRef can reference to standard Kubernetes resources, i.e.
+ Secret, or implementation-specific custom resources.
+
+ This setting can be overridden on the service level by use of BackendTLSPolicy.
+
+ Support: Core
+
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Secret
+ description: Kind is kind of the referent. For example "Secret".
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the referenced object. When unspecified, the local
+ namespace is inferred.
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ required:
+ - name
+ type: object
+ type: object
gatewayClassName:
description: |-
GatewayClassName used for this Gateway. This is the name of a
@@ -3109,13 +3071,10 @@ spec:
minLength: 1
type: string
infrastructure:
- description: |+
+ description: |-
Infrastructure defines infrastructure level attributes about this Gateway instance.
-
- Support: Core
-
-
+ Support: Extended
properties:
annotations:
additionalProperties:
@@ -3130,56 +3089,74 @@ spec:
description: |-
Annotations that SHOULD be applied to any resources created in response to this Gateway.
-
For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources.
For other implementations, this refers to any relevant (implementation specific) "annotations" concepts.
-
An implementation may chose to add additional implementation-specific annotations as they see fit.
-
Support: Extended
maxProperties: 8
type: object
+ x-kubernetes-validations:
+ - message: Annotation keys must be in the form of an optional
+ DNS subdomain prefix followed by a required name segment of
+ up to 63 characters.
+ rule: self.all(key, key.matches(r"""^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$"""))
+ - message: If specified, the annotation key's prefix must be a
+ DNS subdomain not longer than 253 characters in total.
+ rule: self.all(key, key.split("/")[0].size() < 253)
labels:
additionalProperties:
description: |-
- AnnotationValue is the value of an annotation in Gateway API. This is used
- for validation of maps such as TLS options. This roughly matches Kubernetes
- annotation validation, although the length validation in that case is based
- on the entire size of the annotations struct.
- maxLength: 4096
+ LabelValue is the value of a label in the Gateway API. This is used for validation
+ of maps such as Gateway infrastructure labels. This matches the Kubernetes
+ label validation rules:
+ * must be 63 characters or less (can be empty),
+ * unless empty, must begin and end with an alphanumeric character ([a-z0-9A-Z]),
+ * could contain dashes (-), underscores (_), dots (.), and alphanumerics between.
+
+ Valid values include:
+
+ * MyValue
+ * my.name
+ * 123-my-value
+ maxLength: 63
minLength: 0
+ pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$
type: string
description: |-
Labels that SHOULD be applied to any resources created in response to this Gateway.
-
For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources.
For other implementations, this refers to any relevant (implementation specific) "labels" concepts.
-
An implementation may chose to add additional implementation-specific labels as they see fit.
+ If an implementation maps these labels to Pods, or any other resource that would need to be recreated when labels
+ change, it SHOULD clearly warn about this behavior in documentation.
Support: Extended
maxProperties: 8
type: object
+ x-kubernetes-validations:
+ - message: Label keys must be in the form of an optional DNS subdomain
+ prefix followed by a required name segment of up to 63 characters.
+ rule: self.all(key, key.matches(r"""^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$"""))
+ - message: If specified, the label key's prefix must be a DNS
+ subdomain not longer than 253 characters in total.
+ rule: self.all(key, key.split("/")[0].size() < 253)
parametersRef:
description: |-
ParametersRef is a reference to a resource that contains the configuration
parameters corresponding to the Gateway. This is optional if the
controller does not require any additional configuration.
-
This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis
-
The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified,
the merging behavior is implementation specific.
It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.
-
Support: Implementation-specific
properties:
group:
@@ -3210,7 +3187,6 @@ spec:
logical endpoints that are bound on this Gateway's addresses.
At least one Listener MUST be specified.
-
Each Listener in a set of Listeners (for example, in a single Gateway)
MUST be _distinct_, in that a traffic flow MUST be able to be assigned to
exactly one listener. (This section uses "set of Listeners" rather than
@@ -3218,42 +3194,32 @@ spec:
from multiple Gateways onto a single data plane, and these rules _also_
apply in that case).
-
Practically, this means that each listener in a set MUST have a unique
combination of Port, Protocol, and, if supported by the protocol, Hostname.
-
Some combinations of port, protocol, and TLS settings are considered
Core support and MUST be supported by implementations based on their
targeted conformance profile:
-
HTTP Profile
-
1. HTTPRoute, Port: 80, Protocol: HTTP
2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided
-
TLS Profile
-
1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough
-
"Distinct" Listeners have the following property:
-
The implementation can match inbound requests to a single distinct
Listener. When multiple Listeners share values for fields (for
example, two Listeners with the same Port value), the implementation
can match requests to only one of the Listeners using other
Listener fields.
-
For example, the following Listener scenarios are distinct:
-
1. Multiple Listeners with the same Port that all use the "HTTP"
Protocol that all have unique Hostname values.
2. Multiple Listeners with the same Port that use either the "HTTPS" or
@@ -3261,45 +3227,37 @@ spec:
3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener
with the same Protocol has the same Port value.
-
Some fields in the Listener struct have possible values that affect
whether the Listener is distinct. Hostname is particularly relevant
for HTTP or HTTPS protocols.
-
When using the Hostname value to select between same-Port, same-Protocol
Listeners, the Hostname value must be different on each Listener for the
Listener to be distinct.
-
When the Listeners are distinct based on Hostname, inbound request
hostnames MUST match from the most specific to least specific Hostname
values to choose the correct Listener and its associated set of Routes.
-
Exact matches must be processed before wildcard matches, and wildcard
matches must be processed before fallback (empty Hostname value)
matches. For example, `"foo.example.com"` takes precedence over
`"*.example.com"`, and `"*.example.com"` takes precedence over `""`.
-
Additionally, if there are multiple wildcard entries, more specific
wildcard entries must be processed before less specific wildcard entries.
For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`.
The precise definition here is that the higher the number of dots in the
hostname to the right of the wildcard character, the higher the precedence.
-
The wildcard character will match any number of characters _and dots_ to
the left, however, so `"*.example.com"` will match both
`"foo.bar.example.com"` _and_ `"bar.example.com"`.
-
If a set of Listeners contains Listeners that are not distinct, then those
Listeners are Conflicted, and the implementation MUST set the "Conflicted"
condition in the Listener Status to "True".
-
Implementations MAY choose to accept a Gateway with some Conflicted
Listeners only if they only accept the partial Listener set that contains
no Conflicted Listeners. To put this another way, implementations may
@@ -3309,7 +3267,6 @@ spec:
Listener in this case, otherwise it violates the requirement that at
least one Listener must be present.
-
The implementation MUST set a "ListenersNotValid" condition on the
Gateway Status when the Gateway contains Conflicted Listeners whether or
not they accept the Gateway. That Condition SHOULD clearly
@@ -3317,26 +3274,21 @@ spec:
Accepted. Additionally, the Listener status for those listeners SHOULD
indicate which Listeners are conflicted and not Accepted.
-
A Gateway's Listeners are considered "compatible" if:
-
1. They are distinct.
2. The implementation can serve them in compliance with the Addresses
requirement that all Listeners are available on all assigned
addresses.
-
Compatible combinations in Extended support are expected to vary across
implementations. A combination that is compatible for one implementation
may not be compatible for another.
-
For example, an implementation that cannot serve both TCP and UDP listeners
on the same address, or cannot mix HTTPS and generic TLS listens on the same port
would not consider those cases compatible, even though they are distinct.
-
Note that requests SHOULD match at most one Listener. For example, if
Listeners are defined for "foo.example.com" and "*.example.com", a
request to "foo.example.com" SHOULD only be routed using routes attached
@@ -3344,11 +3296,9 @@ spec:
This concept is known as "Listener Isolation". Implementations that do
not support Listener Isolation MUST clearly document this.
-
Implementations MAY merge separate Gateways onto a single set of
Addresses if all Listeners across all Gateways are compatible.
-
Support: Core
items:
description: |-
@@ -3364,12 +3314,10 @@ spec:
Listener and the trusted namespaces where those Route resources MAY be
present.
-
Although a client request may match multiple route rules, only one rule
may ultimately receive the request. Matching precedence MUST be
determined in order of the following criteria:
-
* The most specific match as defined by the Route type.
* The oldest Route based on creation timestamp. For example, a Route with
a creation timestamp of "2020-09-08 01:02:03" is given precedence over
@@ -3378,7 +3326,6 @@ spec:
alphabetical order (namespace/name) should be given precedence. For
example, foo/bar is given precedence over foo/baz.
-
All valid rules within a Route attached to this Listener should be
implemented. Invalid Route rules can be ignored (sometimes that will mean
the full Route). If a Route rule transitions from valid to invalid,
@@ -3386,7 +3333,6 @@ spec:
example, even if a filter specified by a Route rule is invalid, the rest
of the rules within that Route should still be supported.
-
Support: Core
properties:
kinds:
@@ -3395,14 +3341,12 @@ spec:
to this Gateway Listener. When unspecified or empty, the kinds of Routes
selected are determined using the Listener protocol.
-
A RouteGroupKind MUST correspond to kinds of Routes that are compatible
with the application protocol specified in the Listener's Protocol field.
If an implementation does not support or recognize this resource type, it
MUST set the "ResolvedRefs" condition to False for this Listener with the
"InvalidRouteKinds" reason.
-
Support: Core
items:
description: RouteGroupKind indicates the group and kind
@@ -3432,7 +3376,6 @@ spec:
Namespaces indicates namespaces from which Routes may be attached to this
Listener. This is restricted to the namespace of this Gateway by default.
-
Support: Core
properties:
from:
@@ -3441,13 +3384,11 @@ spec:
From indicates where Routes will be selected for this Gateway. Possible
values are:
-
* All: Routes in all namespaces may be used by this Gateway.
* Selector: Routes in namespaces selected by the selector may be used by
this Gateway.
* Same: Only Routes in the same namespace may be used by this Gateway.
-
Support: Core
enum:
- All
@@ -3460,7 +3401,6 @@ spec:
only Routes in Namespaces matching this Selector will be selected by this
Gateway. This field is ignored for other values of "From".
-
Support: Core
properties:
matchExpressions:
@@ -3515,11 +3455,9 @@ spec:
field is ignored for protocols that don't require hostname based
matching.
-
Implementations MUST apply Hostname matching appropriately for each of
the following protocols:
-
* TLS: The Listener Hostname MUST match the SNI.
* HTTP: The Listener Hostname MUST match the Host header of the request.
* HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP
@@ -3527,19 +3465,16 @@ spec:
ensure that both the SNI and Host header match the Listener hostname,
it MUST clearly document that.
-
For HTTPRoute and TLSRoute resources, there is an interaction with the
`spec.hostnames` array. When both listener and route specify hostnames,
there MUST be an intersection between the values for a Route to be
accepted. For more information, refer to the Route specific Hostnames
documentation.
-
Hostnames that are prefixed with a wildcard label (`*.`) are interpreted
as a suffix match. That means that a match for `*.example.com` would match
both `test.example.com`, and `foo.test.example.com`, but not `example.com`.
-
Support: Core
maxLength: 253
minLength: 1
@@ -3550,7 +3485,6 @@ spec:
Name is the name of the Listener. This name MUST be unique within a
Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -3561,7 +3495,6 @@ spec:
Port is the network port. Multiple listeners may use the
same port, subject to the Listener compatibility rules.
-
Support: Core
format: int32
maximum: 65535
@@ -3571,11 +3504,10 @@ spec:
description: |-
Protocol specifies the network protocol this listener expects to receive.
-
Support: Core
maxLength: 255
minLength: 1
- pattern: ^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$
+ pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$
type: string
tls:
description: |-
@@ -3583,15 +3515,12 @@ spec:
the Protocol field is "HTTPS" or "TLS". It is invalid to set this field
if the Protocol field is "HTTP", "TCP", or "UDP".
-
The association of SNIs to Certificate defined in GatewayTLSConfig is
defined based on the Hostname field for this listener.
-
The GatewayClass MUST use the longest matching SNI out of all
available certificates for any TLS handshake.
-
Support: Core
properties:
certificateRefs:
@@ -3601,41 +3530,33 @@ spec:
establish a TLS handshake for requests that match the hostname of the
associated listener.
-
A single CertificateRef to a Kubernetes Secret has "Core" support.
Implementations MAY choose to support attaching multiple certificates to
a Listener, but this behavior is implementation-specific.
-
References to a resource in different namespace are invalid UNLESS there
is a ReferenceGrant in the target namespace that allows the certificate
to be attached. If a ReferenceGrant does not allow this reference, the
"ResolvedRefs" condition MUST be set to False for this listener with the
"RefNotPermitted" reason.
-
This field is required to have at least one element when the mode is set
to "Terminate" (default) and is optional otherwise.
-
CertificateRefs can reference to standard Kubernetes resources, i.e.
Secret, or implementation-specific custom resources.
-
Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls
-
Support: Implementation-specific (More than one reference or other resource types)
items:
description: |-
SecretObjectReference identifies an API object including its namespace,
defaulting to Secret.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
-
References to objects with invalid Group and Kind are not valid, and must
be rejected by the implementation, with appropriate Conditions set
on the containing object.
@@ -3666,13 +3587,11 @@ spec:
Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -3691,10 +3610,8 @@ spec:
that requests a user to specify the client certificate.
The maximum depth of a certificate chain accepted in verification is Implementation specific.
-
Support: Extended
-
properties:
caCertificateRefs:
description: |-
@@ -3703,21 +3620,17 @@ spec:
the Certificate Authorities that can be used
as a trust anchor to validate the certificates presented by the client.
-
A single CA certificate reference to a Kubernetes ConfigMap
has "Core" support.
Implementations MAY choose to support attaching multiple CA certificates to
a Listener, but this behavior is implementation-specific.
-
Support: Core - A single reference to a Kubernetes ConfigMap
with the CA certificate in a key named `ca.crt`.
-
Support: Implementation-specific (More than one reference, or other kinds
of resources).
-
References to a resource in a different namespace are invalid UNLESS there
is a ReferenceGrant in the target namespace that allows the certificate
to be attached. If a ReferenceGrant does not allow this reference, the
@@ -3727,11 +3640,9 @@ spec:
description: |-
ObjectReference identifies an API object including its namespace.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
-
References to objects with invalid Group and Kind are not valid, and must
be rejected by the implementation, with appropriate Conditions set
on the containing object.
@@ -3760,13 +3671,11 @@ spec:
Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -3787,7 +3696,6 @@ spec:
Mode defines the TLS behavior for the TLS session initiated by the client.
There are two possible modes:
-
- Terminate: The TLS session between the downstream client and the
Gateway is terminated at the Gateway. This mode requires certificates
to be specified in some way, such as populating the certificateRefs
@@ -3797,7 +3705,6 @@ spec:
the ClientHello message of the TLS protocol. The certificateRefs field
is ignored in this mode.
-
Support: Core
enum:
- Terminate
@@ -3818,13 +3725,11 @@ spec:
configuration for each implementation. For example, configuring the
minimum TLS version or supported cipher suites.
-
A set of common keys MAY be defined by the API in the future. To avoid
any ambiguity, implementation-specific definitions MUST use
domain-prefixed names, such as `example.com/my-custom-option`.
Un-prefixed names are reserved for key names defined by Gateway API.
-
Support: Implementation-specific
maxProperties: 16
type: object
@@ -3887,16 +3792,13 @@ spec:
Addresses lists the network addresses that have been bound to the
Gateway.
-
This list may differ from the addresses provided in the spec under some
conditions:
-
* no addresses are specified, all addresses are dynamically assigned
* a combination of specified and dynamic addresses are assigned
* a specified address was unusable (e.g. already in use)
-
items:
description: GatewayStatusAddress describes a network address that
is bound to a Gateway.
@@ -3927,7 +3829,6 @@ spec:
Value of the address. The validity of the values will depend
on the type and support by the controller.
-
Examples: `1.2.3.4`, `128::1`, `my-ip-address`.
maxLength: 253
minLength: 1
@@ -3957,30 +3858,19 @@ spec:
description: |-
Conditions describe the current conditions of the Gateway.
-
Implementations should prefer to express Gateway conditions
using the `GatewayConditionType` and `GatewayConditionReason`
constants so that operators and tools can converge on a common
vocabulary to describe Gateway state.
-
Known condition types are:
-
* "Accepted"
* "Programmed"
* "Ready"
items:
- description: "Condition contains details for one aspect of the current
- state of this API Resource.\n---\nThis struct is intended for
- direct use as an array at the field path .status.conditions. For
- example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
- observations of a foo's current state.\n\t // Known .status.conditions.type
- are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
- \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
- patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of the current
+ state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -4021,12 +3911,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -4053,7 +3938,6 @@ spec:
AttachedRoutes represents the total number of Routes that have been
successfully attached to this Listener.
-
Successful attachment of a Route to a Listener is based solely on the
combination of the AllowedRoutes field on the corresponding Listener
and the Route's ParentRefs field. A Route is successfully attached to
@@ -4066,7 +3950,6 @@ spec:
for Listeners with condition Accepted: false and MUST count successfully
attached Routes that may themselves have Accepted: false conditions.
-
Uses for this field include troubleshooting Route attachment and
measuring blast radius/impact of changes to a Listener.
format: int32
@@ -4075,18 +3958,8 @@ spec:
description: Conditions describe the current condition of this
listener.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -4128,12 +4001,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -4162,7 +4030,6 @@ spec:
listener. This MUST represent the kinds an implementation supports for
that Listener configuration.
-
If kinds are specified in Spec that are not supported, they MUST NOT
appear in this list and an implementation MUST set the "ResolvedRefs"
condition to "False" with the "InvalidRouteKinds" reason. If both valid
@@ -4222,8 +4089,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
- gateway.networking.k8s.io/bundle-version: v1.1.0
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+ gateway.networking.k8s.io/bundle-version: v1.2.1
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: grpcroutes.gateway.networking.k8s.io
@@ -4254,14 +4121,12 @@ spec:
Filters can be used to specify additional processing steps. Backends specify
where matching requests will be routed.
-
GRPCRoute falls under extended support within the Gateway API. Within the
following specification, the word "MUST" indicates that an implementation
supporting GRPCRoute must conform to the indicated requirement, but an
implementation not supporting this route type need not follow the requirement
unless explicitly indicated.
-
Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST
accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via
ALPN. If the implementation does not support this, then it MUST set the
@@ -4269,7 +4134,6 @@ spec:
"UnsupportedProtocol". Implementations MAY also accept HTTP/2 connections
with an upgrade from HTTP/1.
-
Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST
support HTTP/2 over cleartext TCP (h2c,
https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial
@@ -4306,17 +4170,14 @@ spec:
Host header to select a GRPCRoute to process the request. This matches
the RFC 1123 definition of a hostname with 2 notable exceptions:
-
1. IPs are not allowed.
2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
label MUST appear by itself as the first label.
-
If a hostname is specified by both the Listener and GRPCRoute, there
MUST be at least one intersecting hostname for the GRPCRoute to be
attached to the Listener. For example:
-
* A Listener with `test.example.com` as the hostname matches GRPCRoutes
that have either not specified any hostnames, or have specified at
least one of `test.example.com` or `*.example.com`.
@@ -4326,58 +4187,48 @@ spec:
`test.example.com` and `*.example.com` would both match. On the other
hand, `example.com` and `test.example.net` would not match.
-
Hostnames that are prefixed with a wildcard label (`*.`) are interpreted
as a suffix match. That means that a match for `*.example.com` would match
both `test.example.com`, and `foo.test.example.com`, but not `example.com`.
-
If both the Listener and GRPCRoute have specified hostnames, any
GRPCRoute hostnames that do not match the Listener hostname MUST be
ignored. For example, if a Listener specified `*.example.com`, and the
GRPCRoute specified `test.example.com` and `test.example.net`,
`test.example.net` MUST NOT be considered for a match.
-
If both the Listener and GRPCRoute have specified hostnames, and none
match with the criteria above, then the GRPCRoute MUST NOT be accepted by
the implementation. The implementation MUST raise an 'Accepted' Condition
with a status of `False` in the corresponding RouteParentStatus.
-
If a Route (A) of type HTTPRoute or GRPCRoute is attached to a
Listener and that listener already has another Route (B) of the other
type attached and the intersection of the hostnames of A and B is
non-empty, then the implementation MUST accept exactly one of these two
routes, determined by the following criteria, in order:
-
* The oldest Route based on creation timestamp.
* The Route appearing first in alphabetical order by
"{namespace}/{name}".
-
The rejected Route MUST raise an 'Accepted' condition with a status of
'False' in the corresponding RouteParentStatus.
-
Support: Core
items:
description: |-
Hostname is the fully qualified domain name of a network host. This matches
the RFC 1123 definition of a hostname with 2 notable exceptions:
-
1. IPs are not allowed.
2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
label must appear by itself as the first label.
-
Hostname can be "precise" which is a domain name without the terminating
dot of a network host (e.g. "foo.example.com") or "wildcard", which is a
domain name prefixed with a single wildcard label (e.g. `*.example.com`).
-
Note that as per RFC1035 and RFC1123, a *label* must consist of lower case
alphanumeric characters or '-', and must start and end with an alphanumeric
character. No other punctuation is allowed.
@@ -4400,21 +4251,16 @@ spec:
create a "producer" route for a Service in a different namespace from the
Route.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
ParentRefs must be _distinct_. This means either that:
-
* They select different objects. If this is the case, then parentRef
entries are distinct. In terms of fields, this means that the
multi-part key defined by `group`, `kind`, `namespace`, and `name` must
@@ -4424,10 +4270,8 @@ spec:
optional fields to different values. If one ParentRef sets a
combination of optional fields, all must set the same combination.
-
Some examples:
-
* If one ParentRef sets `sectionName`, all ParentRefs referencing the
same object must also set `sectionName`.
* If one ParentRef sets `port`, all ParentRefs referencing the same
@@ -4435,14 +4279,12 @@ spec:
* If one ParentRef sets `sectionName` and `port`, all ParentRefs
referencing the same object must also set `sectionName` and `port`.
-
It is possible to separately reference multiple distinct objects that may
be collapsed by an implementation. For example, some implementations may
choose to merge compatible Gateway Listeners together. If that is the
case, the list of routes attached to those resources should also be
merged.
-
Note that for ParentRefs that cross namespace boundaries, there are specific
rules. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example,
@@ -4450,12 +4292,10 @@ spec:
generic way to enable other kinds of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -4466,22 +4306,18 @@ spec:
-
items:
description: |-
ParentReference identifies an API object (usually a Gateway) that can be considered
a parent of this resource (usually a route). There are two kinds of parent resources
with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
properties:
@@ -4493,7 +4329,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -4503,14 +4338,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -4520,7 +4352,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -4530,7 +4361,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -4538,12 +4368,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -4551,7 +4379,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -4562,7 +4389,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -4572,18 +4398,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -4592,7 +4415,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -4603,7 +4425,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -4611,12 +4432,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -4626,7 +4445,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -4661,7 +4479,9 @@ spec:
|| p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port
== p2.port))))
rules:
- description: Rules are a list of GRPC matchers, filters and actions.
+ description: |+
+ Rules are a list of GRPC matchers, filters and actions.
+
items:
description: |-
GRPCRouteRule defines the semantics for matching a gRPC request based on
@@ -4673,71 +4493,56 @@ spec:
BackendRefs defines the backend(s) where matching requests should be
sent.
-
Failure behavior here depends on how many BackendRefs are specified and
how many are invalid.
-
If *all* entries in BackendRefs are invalid, and there are also no filters
specified in this route rule, *all* traffic which matches this rule MUST
receive an `UNAVAILABLE` status.
-
See the GRPCBackendRef definition for the rules about what makes a single
GRPCBackendRef invalid.
-
When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for
requests that would have otherwise been routed to an invalid backend. If
multiple backends are specified, and some are invalid, the proportion of
requests that would otherwise have been routed to an invalid backend
MUST receive an `UNAVAILABLE` status.
-
For example, if two backends are specified with equal weights, and one is
invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status.
Implementations may choose how that 50 percent is determined.
-
Support: Core for Kubernetes Service
-
Support: Implementation-specific for any other resource
-
Support for weight: Core
items:
description: |-
GRPCBackendRef defines how a GRPCRoute forwards a gRPC request.
-
Note that when a namespace different than the local namespace is specified, a
ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
-
When the BackendRef points to a Kubernetes Service, implementations SHOULD
honor the appProtocol field if it is set for the target Service Port.
-
Implementations supporting appProtocol SHOULD recognize the Kubernetes
Standard Application Protocols defined in KEP-3726.
-
If a Service appProtocol isn't specified, an implementation MAY infer the
backend protocol through its own means. Implementations MAY infer the
protocol from the Route type referring to the backend Service.
-
If a Route is not able to send traffic to the backend using the specified
protocol then the backend is considered invalid. Implementations MUST set the
"ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason.
-
properties:
filters:
@@ -4745,7 +4550,6 @@ spec:
Filters defined at this level MUST be executed if and only if the
request is being forwarded to the backend defined here.
-
Support: Implementation-specific (For broader support of filters, use the
Filters field in GRPCRouteRule.)
items:
@@ -4764,10 +4568,8 @@ spec:
"networking.example.net"). ExtensionRef MUST NOT be used for core and
extended filters.
-
Support: Implementation-specific
-
This filter can be used multiple times within the same rule.
properties:
group:
@@ -4799,7 +4601,6 @@ spec:
RequestHeaderModifier defines a schema for a filter that modifies request
headers.
-
Support: Core
properties:
add:
@@ -4808,18 +4609,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -4833,7 +4631,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -4865,18 +4662,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -4890,18 +4684,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -4915,7 +4706,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -4942,49 +4732,42 @@ spec:
x-kubernetes-list-type: map
type: object
requestMirror:
- description: |-
+ description: |+
RequestMirror defines a schema for a filter that mirrors requests.
Requests are sent to the specified destination, but responses from
that destination are ignored.
-
This filter can be used multiple times within the same rule. Note that
not all implementations will be able to support mirroring to multiple
backends.
-
Support: Extended
+
properties:
backendRef:
description: |-
BackendRef references a resource where mirrored requests are sent.
-
Mirrored requests must be sent only to a single destination endpoint
within this BackendRef, irrespective of how many endpoints are present
within this BackendRef.
-
If the referent cannot be found, this BackendRef is invalid and must be
dropped from the Gateway. The controller must ensure the "ResolvedRefs"
condition on the Route status is set to `status: False` and not configure
this backend in the underlying implementation.
-
If there is a cross-namespace reference to an *existing* object
that is not allowed by a ReferenceGrant, the controller must ensure the
"ResolvedRefs" condition on the Route is set to `status: False`,
with the "RefNotPermitted" reason and not configure this backend in the
underlying implementation.
-
In either error case, the Message of the `ResolvedRefs` Condition
should be used to provide more detail about the problem.
-
Support: Extended for Kubernetes Service
-
Support: Implementation-specific for any other resource
properties:
group:
@@ -5001,20 +4784,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -5030,13 +4809,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -5060,15 +4837,56 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind
== ''Service'') ? has(self.port) : true'
+ fraction:
+ description: |+
+ Fraction represents the fraction of requests that should be
+ mirrored to BackendRef.
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ properties:
+ denominator:
+ default: 100
+ format: int32
+ minimum: 1
+ type: integer
+ numerator:
+ format: int32
+ minimum: 0
+ type: integer
+ required:
+ - numerator
+ type: object
+ x-kubernetes-validations:
+ - message: numerator must be less than or equal
+ to denominator
+ rule: self.numerator <= self.denominator
+ percent:
+ description: |+
+ Percent represents the percentage of requests that should be
+ mirrored to BackendRef. Its minimum value is 0 (indicating 0% of
+ requests) and its maximum value is 100 (indicating 100% of requests).
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ format: int32
+ maximum: 100
+ minimum: 0
+ type: integer
required:
- backendRef
type: object
+ x-kubernetes-validations:
+ - message: Only one of percent or fraction may be
+ specified in HTTPRequestMirrorFilter
+ rule: '!(has(self.percent) && has(self.fraction))'
responseHeaderModifier:
description: |-
ResponseHeaderModifier defines a schema for a filter that modifies response
headers.
-
Support: Extended
properties:
add:
@@ -5077,18 +4895,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -5102,7 +4917,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -5134,18 +4948,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -5159,18 +4970,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -5184,7 +4992,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -5215,17 +5022,14 @@ spec:
Type identifies the type of filter to apply. As with other API fields,
types are classified into three conformance levels:
-
- Core: Filter types and their corresponding configuration defined by
"Support: Core" in this package, e.g. "RequestHeaderModifier". All
implementations supporting GRPCRoute MUST support core filters.
-
- Extended: Filter types and their corresponding configuration defined by
"Support: Extended" in this package, e.g. "RequestMirror". Implementers
are encouraged to support extended filters.
-
- Implementation-specific: Filters that are defined and supported by specific vendors.
In the future, filters showing convergence in behavior across multiple
implementations will be considered for inclusion in extended or core
@@ -5233,16 +5037,13 @@ spec:
is specified using the ExtensionRef field. `Type` MUST be set to
"ExtensionRef" for custom filters.
-
Implementers are encouraged to define custom implementation types to
extend the core API with implementation-specific behavior.
-
If a reference to a custom filter type cannot be resolved, the filter
MUST NOT be skipped. Instead, requests that would have been processed by
that filter MUST receive a HTTP error response.
-
enum:
- ResponseHeaderModifier
- RequestHeaderModifier
@@ -5305,20 +5106,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -5334,13 +5131,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -5367,13 +5162,11 @@ spec:
implementation supports. Weight is not a percentage and the sum of
weights does not need to equal 100.
-
If only one backend is specified and it has a weight greater than 0, 100%
of the traffic is forwarded to that backend. If weight is set to 0, no
traffic should be forwarded for this entry. If unspecified, weight
defaults to 1.
-
Support for this field varies based on the context where used.
format: int32
maximum: 1000000
@@ -5393,32 +5186,26 @@ spec:
Filters define the filters that are applied to requests that match
this rule.
-
The effects of ordering of multiple behaviors are currently unspecified.
This can change in the future based on feedback during the alpha stage.
-
Conformance-levels at this level are defined based on the type of filter:
-
- ALL core filters MUST be supported by all implementations that support
GRPCRoute.
- Implementers are encouraged to support extended filters.
- Implementation-specific custom filters have no API guarantees across
implementations.
-
Specifying the same filter multiple times is not supported unless explicitly
indicated in the filter.
-
If an implementation can not support a combination of filters, it must clearly
document that limitation. In cases where incompatible or unsupported
filters are specified and cause the `Accepted` condition to be set to status
`False`, implementations may use the `IncompatibleFilters` reason to specify
this configuration error.
-
Support: Core
items:
description: |-
@@ -5436,10 +5223,8 @@ spec:
"networking.example.net"). ExtensionRef MUST NOT be used for core and
extended filters.
-
Support: Implementation-specific
-
This filter can be used multiple times within the same rule.
properties:
group:
@@ -5471,7 +5256,6 @@ spec:
RequestHeaderModifier defines a schema for a filter that modifies request
headers.
-
Support: Core
properties:
add:
@@ -5480,18 +5264,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -5504,7 +5285,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -5536,18 +5316,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -5561,18 +5338,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -5585,7 +5359,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -5612,49 +5385,42 @@ spec:
x-kubernetes-list-type: map
type: object
requestMirror:
- description: |-
+ description: |+
RequestMirror defines a schema for a filter that mirrors requests.
Requests are sent to the specified destination, but responses from
that destination are ignored.
-
This filter can be used multiple times within the same rule. Note that
not all implementations will be able to support mirroring to multiple
backends.
-
Support: Extended
+
properties:
backendRef:
description: |-
BackendRef references a resource where mirrored requests are sent.
-
Mirrored requests must be sent only to a single destination endpoint
within this BackendRef, irrespective of how many endpoints are present
within this BackendRef.
-
If the referent cannot be found, this BackendRef is invalid and must be
dropped from the Gateway. The controller must ensure the "ResolvedRefs"
condition on the Route status is set to `status: False` and not configure
this backend in the underlying implementation.
-
If there is a cross-namespace reference to an *existing* object
that is not allowed by a ReferenceGrant, the controller must ensure the
"ResolvedRefs" condition on the Route is set to `status: False`,
with the "RefNotPermitted" reason and not configure this backend in the
underlying implementation.
-
In either error case, the Message of the `ResolvedRefs` Condition
should be used to provide more detail about the problem.
-
Support: Extended for Kubernetes Service
-
Support: Implementation-specific for any other resource
properties:
group:
@@ -5671,20 +5437,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -5700,13 +5462,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -5730,15 +5490,56 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
+ fraction:
+ description: |+
+ Fraction represents the fraction of requests that should be
+ mirrored to BackendRef.
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ properties:
+ denominator:
+ default: 100
+ format: int32
+ minimum: 1
+ type: integer
+ numerator:
+ format: int32
+ minimum: 0
+ type: integer
+ required:
+ - numerator
+ type: object
+ x-kubernetes-validations:
+ - message: numerator must be less than or equal to
+ denominator
+ rule: self.numerator <= self.denominator
+ percent:
+ description: |+
+ Percent represents the percentage of requests that should be
+ mirrored to BackendRef. Its minimum value is 0 (indicating 0% of
+ requests) and its maximum value is 100 (indicating 100% of requests).
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ format: int32
+ maximum: 100
+ minimum: 0
+ type: integer
required:
- backendRef
type: object
+ x-kubernetes-validations:
+ - message: Only one of percent or fraction may be specified
+ in HTTPRequestMirrorFilter
+ rule: '!(has(self.percent) && has(self.fraction))'
responseHeaderModifier:
description: |-
ResponseHeaderModifier defines a schema for a filter that modifies response
headers.
-
Support: Extended
properties:
add:
@@ -5747,18 +5548,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -5771,7 +5569,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -5803,18 +5600,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -5828,18 +5622,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -5852,7 +5643,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -5883,17 +5673,14 @@ spec:
Type identifies the type of filter to apply. As with other API fields,
types are classified into three conformance levels:
-
- Core: Filter types and their corresponding configuration defined by
"Support: Core" in this package, e.g. "RequestHeaderModifier". All
implementations supporting GRPCRoute MUST support core filters.
-
- Extended: Filter types and their corresponding configuration defined by
"Support: Extended" in this package, e.g. "RequestMirror". Implementers
are encouraged to support extended filters.
-
- Implementation-specific: Filters that are defined and supported by specific vendors.
In the future, filters showing convergence in behavior across multiple
implementations will be considered for inclusion in extended or core
@@ -5901,16 +5688,13 @@ spec:
is specified using the ExtensionRef field. `Type` MUST be set to
"ExtensionRef" for custom filters.
-
Implementers are encouraged to define custom implementation types to
extend the core API with implementation-specific behavior.
-
If a reference to a custom filter type cannot be resolved, the filter
MUST NOT be skipped. Instead, requests that would have been processed by
that filter MUST receive a HTTP error response.
-
enum:
- ResponseHeaderModifier
- RequestHeaderModifier
@@ -5964,10 +5748,8 @@ spec:
gRPC requests. Each match is independent, i.e. this rule will be matched
if **any** one of the matches is satisfied.
-
For example, take the following matches configuration:
-
```
matches:
- method:
@@ -5979,44 +5761,35 @@ spec:
service: foo.bar.v2
```
-
For a request to match against this rule, it MUST satisfy
EITHER of the two conditions:
-
- service of foo.bar AND contains the header `version: 2`
- service of foo.bar.v2
-
See the documentation for GRPCRouteMatch on how to specify multiple
match conditions to be ANDed together.
-
If no matches are specified, the implementation MUST match every gRPC request.
-
Proxy or Load Balancer routing configuration generated from GRPCRoutes
MUST prioritize rules based on the following criteria, continuing on
ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes.
Precedence MUST be given to the rule with the largest number of:
-
* Characters in a matching non-wildcard hostname.
* Characters in a matching hostname.
* Characters in a matching service.
* Characters in a matching method.
* Header matches.
-
If ties still exist across multiple Routes, matching precedence MUST be
determined in order of the following criteria, continuing on ties:
-
* The oldest Route based on creation timestamp.
* The Route appearing first in alphabetical order by
"{namespace}/{name}".
-
If ties still exist within the Route that has been given precedence,
matching precedence MUST be granted to the first matching rule meeting
the above criteria.
@@ -6026,11 +5799,9 @@ spec:
action. Multiple match types are ANDed together, i.e. the match will
evaluate to true only if all conditions are satisfied.
-
For example, the match below will match a gRPC request only if its service
is `foo` AND it contains the `version: v1` header:
-
```
matches:
- method:
@@ -6040,7 +5811,6 @@ spec:
- name: "version"
value "v1"
-
```
properties:
headers:
@@ -6057,7 +5827,6 @@ spec:
description: |-
Name is the name of the gRPC Header to be matched.
-
If multiple entries specify equivalent header names, only the first
entry with an equivalent name MUST be considered for a match. Subsequent
entries with an equivalent header name MUST be ignored. Due to the
@@ -6100,7 +5869,6 @@ spec:
Value of the method to match against. If left empty or omitted, will
match all services.
-
At least one of Service and Method MUST be a non-empty string.
maxLength: 1024
type: string
@@ -6109,7 +5877,6 @@ spec:
Value of the service to match against. If left empty or omitted, will
match any service.
-
At least one of Service and Method MUST be a non-empty string.
maxLength: 1024
type: string
@@ -6119,10 +5886,8 @@ spec:
Type specifies how to match against the service and/or method.
Support: Core (Exact with service and method specified)
-
Support: Implementation-specific (Exact with method specified but no service specified)
-
Support: Implementation-specific (RegularExpression)
enum:
- Exact
@@ -6147,15 +5912,22 @@ spec:
type: object
maxItems: 8
type: array
+ name:
+ description: |
+ Name is the name of the route rule. This name MUST be unique within a Route if it is set.
+
+ Support: Extended
+ maxLength: 253
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
sessionPersistence:
description: |+
SessionPersistence defines and configures session persistence
for the route rule.
-
Support: Extended
-
properties:
absoluteTimeout:
description: |-
@@ -6163,7 +5935,6 @@ spec:
session. Once the AbsoluteTimeout duration has elapsed, the
session becomes invalid.
-
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
@@ -6172,7 +5943,6 @@ spec:
CookieConfig provides configuration settings that are specific
to cookie-based session persistence.
-
Support: Core
properties:
lifetimeType:
@@ -6184,20 +5954,16 @@ spec:
attributes, while a session cookie is deleted when the current
session ends.
-
When set to "Permanent", AbsoluteTimeout indicates the
cookie's lifetime via the Expires or Max-Age cookie attributes
and is required.
-
When set to "Session", AbsoluteTimeout indicates the
absolute lifetime of the cookie tracked by the gateway and
is optional.
-
Support: Core for "Session" type
-
Support: Extended for "Permanent" type
enum:
- Permanent
@@ -6210,7 +5976,6 @@ spec:
Once the session has been idle for more than the specified
IdleTimeout duration, the session becomes invalid.
-
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
@@ -6221,7 +5986,6 @@ spec:
should avoid reusing session names to prevent unintended
consequences, such as rejection or unpredictable behavior.
-
Support: Implementation-specific
maxLength: 128
type: string
@@ -6232,10 +5996,8 @@ spec:
the use a header or cookie. Defaults to cookie based session
persistence.
-
Support: Core for "Cookie" type
-
Support: Extended for "Header" type
enum:
- Cookie
@@ -6245,11 +6007,35 @@ spec:
x-kubernetes-validations:
- message: AbsoluteTimeout must be specified when cookie lifetimeType
is Permanent
- rule: '!has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType
- != ''Permanent'' || has(self.absoluteTimeout)'
+ rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType)
+ || self.cookieConfig.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)'
type: object
maxItems: 16
type: array
+ x-kubernetes-validations:
+ - message: While 16 rules and 64 matches per rule are allowed, the
+ total number of matches across all rules in a route must be less
+ than 128
+ rule: '(self.size() > 0 ? (has(self[0].matches) ? self[0].matches.size()
+ : 0) : 0) + (self.size() > 1 ? (has(self[1].matches) ? self[1].matches.size()
+ : 0) : 0) + (self.size() > 2 ? (has(self[2].matches) ? self[2].matches.size()
+ : 0) : 0) + (self.size() > 3 ? (has(self[3].matches) ? self[3].matches.size()
+ : 0) : 0) + (self.size() > 4 ? (has(self[4].matches) ? self[4].matches.size()
+ : 0) : 0) + (self.size() > 5 ? (has(self[5].matches) ? self[5].matches.size()
+ : 0) : 0) + (self.size() > 6 ? (has(self[6].matches) ? self[6].matches.size()
+ : 0) : 0) + (self.size() > 7 ? (has(self[7].matches) ? self[7].matches.size()
+ : 0) : 0) + (self.size() > 8 ? (has(self[8].matches) ? self[8].matches.size()
+ : 0) : 0) + (self.size() > 9 ? (has(self[9].matches) ? self[9].matches.size()
+ : 0) : 0) + (self.size() > 10 ? (has(self[10].matches) ? self[10].matches.size()
+ : 0) : 0) + (self.size() > 11 ? (has(self[11].matches) ? self[11].matches.size()
+ : 0) : 0) + (self.size() > 12 ? (has(self[12].matches) ? self[12].matches.size()
+ : 0) : 0) + (self.size() > 13 ? (has(self[13].matches) ? self[13].matches.size()
+ : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size()
+ : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size()
+ : 0) : 0) <= 128'
+ - message: Rule name must be unique within the route
+ rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)
+ && l1.name == l2.name))
type: object
status:
description: Status defines the current state of GRPCRoute.
@@ -6263,13 +6049,11 @@ spec:
first sees the route and should update the entry as appropriate when the
route or gateway is modified.
-
Note that parent references that cannot be resolved by an implementation
of this API will not be added to this list. Implementations of this API
can only populate Route status for the Gateways/parent resources they are
responsible for.
-
A maximum of 32 Gateways will be represented in this list. An empty list
means the route has not been attached to any Gateway.
items:
@@ -6283,38 +6067,24 @@ spec:
Note that the route's availability is also subject to the Gateway's own
status conditions and listener status.
-
If the Route's ParentRef specifies an existing Gateway that supports
Routes of this kind AND that Gateway's controller has sufficient access,
then that Gateway's controller MUST set the "Accepted" condition on the
Route, to indicate whether the route has been accepted or rejected by the
Gateway, and why.
-
A Route MUST be considered "Accepted" if at least one of the Route's
rules is implemented by the Gateway.
-
There are a number of cases where the "Accepted" condition may not be set
due to lack of controller visibility, that includes when:
-
* The Route refers to a non-existent parent.
* The Route is of a type that the controller does not support.
* The Route is in a namespace the controller does not have access to.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -6356,12 +6126,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -6384,15 +6149,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
@@ -6413,7 +6175,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -6423,14 +6184,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -6440,7 +6198,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -6450,7 +6207,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -6458,12 +6214,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -6471,7 +6225,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -6482,7 +6235,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -6492,18 +6244,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -6512,7 +6261,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -6523,7 +6271,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -6531,12 +6278,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -6546,7 +6291,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -6569,2331 +6313,6 @@ spec:
storage: true
subresources:
status: {}
- - deprecated: true
- deprecationWarning: The v1alpha2 version of GRPCRoute has been deprecated and
- will be removed in a future release of the API. Please upgrade to v1.
- name: v1alpha2
- schema:
- openAPIV3Schema:
- description: |-
- GRPCRoute provides a way to route gRPC requests. This includes the capability
- to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header.
- Filters can be used to specify additional processing steps. Backends specify
- where matching requests will be routed.
-
-
- GRPCRoute falls under extended support within the Gateway API. Within the
- following specification, the word "MUST" indicates that an implementation
- supporting GRPCRoute must conform to the indicated requirement, but an
- implementation not supporting this route type need not follow the requirement
- unless explicitly indicated.
-
-
- Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST
- accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via
- ALPN. If the implementation does not support this, then it MUST set the
- "Accepted" condition to "False" for the affected listener with a reason of
- "UnsupportedProtocol". Implementations MAY also accept HTTP/2 connections
- with an upgrade from HTTP/1.
-
-
- Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST
- support HTTP/2 over cleartext TCP (h2c,
- https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial
- upgrade from HTTP/1.1, i.e. with prior knowledge
- (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation
- does not support this, then it MUST set the "Accepted" condition to "False"
- for the affected listener with a reason of "UnsupportedProtocol".
- Implementations MAY also accept HTTP/2 connections with an upgrade from
- HTTP/1, i.e. without prior knowledge.
- properties:
- apiVersion:
- description: |-
- APIVersion defines the versioned schema of this representation of an object.
- Servers should convert recognized schemas to the latest internal value, and
- may reject unrecognized values.
- More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
- type: string
- kind:
- description: |-
- Kind is a string value representing the REST resource this object represents.
- Servers may infer this from the endpoint the client submits requests to.
- Cannot be updated.
- In CamelCase.
- More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
- type: string
- metadata:
- type: object
- spec:
- description: Spec defines the desired state of GRPCRoute.
- properties:
- hostnames:
- description: |-
- Hostnames defines a set of hostnames to match against the GRPC
- Host header to select a GRPCRoute to process the request. This matches
- the RFC 1123 definition of a hostname with 2 notable exceptions:
-
-
- 1. IPs are not allowed.
- 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
- label MUST appear by itself as the first label.
-
-
- If a hostname is specified by both the Listener and GRPCRoute, there
- MUST be at least one intersecting hostname for the GRPCRoute to be
- attached to the Listener. For example:
-
-
- * A Listener with `test.example.com` as the hostname matches GRPCRoutes
- that have either not specified any hostnames, or have specified at
- least one of `test.example.com` or `*.example.com`.
- * A Listener with `*.example.com` as the hostname matches GRPCRoutes
- that have either not specified any hostnames or have specified at least
- one hostname that matches the Listener hostname. For example,
- `test.example.com` and `*.example.com` would both match. On the other
- hand, `example.com` and `test.example.net` would not match.
-
-
- Hostnames that are prefixed with a wildcard label (`*.`) are interpreted
- as a suffix match. That means that a match for `*.example.com` would match
- both `test.example.com`, and `foo.test.example.com`, but not `example.com`.
-
-
- If both the Listener and GRPCRoute have specified hostnames, any
- GRPCRoute hostnames that do not match the Listener hostname MUST be
- ignored. For example, if a Listener specified `*.example.com`, and the
- GRPCRoute specified `test.example.com` and `test.example.net`,
- `test.example.net` MUST NOT be considered for a match.
-
-
- If both the Listener and GRPCRoute have specified hostnames, and none
- match with the criteria above, then the GRPCRoute MUST NOT be accepted by
- the implementation. The implementation MUST raise an 'Accepted' Condition
- with a status of `False` in the corresponding RouteParentStatus.
-
-
- If a Route (A) of type HTTPRoute or GRPCRoute is attached to a
- Listener and that listener already has another Route (B) of the other
- type attached and the intersection of the hostnames of A and B is
- non-empty, then the implementation MUST accept exactly one of these two
- routes, determined by the following criteria, in order:
-
-
- * The oldest Route based on creation timestamp.
- * The Route appearing first in alphabetical order by
- "{namespace}/{name}".
-
-
- The rejected Route MUST raise an 'Accepted' condition with a status of
- 'False' in the corresponding RouteParentStatus.
-
-
- Support: Core
- items:
- description: |-
- Hostname is the fully qualified domain name of a network host. This matches
- the RFC 1123 definition of a hostname with 2 notable exceptions:
-
-
- 1. IPs are not allowed.
- 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
- label must appear by itself as the first label.
-
-
- Hostname can be "precise" which is a domain name without the terminating
- dot of a network host (e.g. "foo.example.com") or "wildcard", which is a
- domain name prefixed with a single wildcard label (e.g. `*.example.com`).
-
-
- Note that as per RFC1035 and RFC1123, a *label* must consist of lower case
- alphanumeric characters or '-', and must start and end with an alphanumeric
- character. No other punctuation is allowed.
- maxLength: 253
- minLength: 1
- pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- maxItems: 16
- type: array
- parentRefs:
- description: |+
- ParentRefs references the resources (usually Gateways) that a Route wants
- to be attached to. Note that the referenced parent resource needs to
- allow this for the attachment to be complete. For Gateways, that means
- the Gateway needs to allow attachment from Routes of this kind and
- namespace. For Services, that means the Service must either be in the same
- namespace for a "producer" route, or the mesh implementation must support
- and allow "consumer" routes for the referenced Service. ReferenceGrant is
- not applicable for governing ParentRefs to Services - it is not possible to
- create a "producer" route for a Service in a different namespace from the
- Route.
-
-
- There are two kinds of parent resources with "Core" support:
-
-
- * Gateway (Gateway conformance profile)
- * Service (Mesh conformance profile, ClusterIP Services only)
-
-
- This API may be extended in the future to support additional kinds of parent
- resources.
-
-
- ParentRefs must be _distinct_. This means either that:
-
-
- * They select different objects. If this is the case, then parentRef
- entries are distinct. In terms of fields, this means that the
- multi-part key defined by `group`, `kind`, `namespace`, and `name` must
- be unique across all parentRef entries in the Route.
- * They do not select different objects, but for each optional field used,
- each ParentRef that selects the same object must set the same set of
- optional fields to different values. If one ParentRef sets a
- combination of optional fields, all must set the same combination.
-
-
- Some examples:
-
-
- * If one ParentRef sets `sectionName`, all ParentRefs referencing the
- same object must also set `sectionName`.
- * If one ParentRef sets `port`, all ParentRefs referencing the same
- object must also set `port`.
- * If one ParentRef sets `sectionName` and `port`, all ParentRefs
- referencing the same object must also set `sectionName` and `port`.
-
-
- It is possible to separately reference multiple distinct objects that may
- be collapsed by an implementation. For example, some implementations may
- choose to merge compatible Gateway Listeners together. If that is the
- case, the list of routes attached to those resources should also be
- merged.
-
-
- Note that for ParentRefs that cross namespace boundaries, there are specific
- rules. Cross-namespace references are only valid if they are explicitly
- allowed by something in the namespace they are referring to. For example,
- Gateway has the AllowedRoutes field, and ReferenceGrant provides a
- generic way to enable other kinds of cross-namespace reference.
-
-
-
- ParentRefs from a Route to a Service in the same namespace are "producer"
- routes, which apply default routing rules to inbound connections from
- any namespace to the Service.
-
-
- ParentRefs from a Route to a Service in a different namespace are
- "consumer" routes, and these routing rules are only applied to outbound
- connections originating from the same namespace as the Route, for which
- the intended destination of the connections are a Service targeted as a
- ParentRef of the Route.
-
-
-
-
-
-
- items:
- description: |-
- ParentReference identifies an API object (usually a Gateway) that can be considered
- a parent of this resource (usually a route). There are two kinds of parent resources
- with "Core" support:
-
-
- * Gateway (Gateway conformance profile)
- * Service (Mesh conformance profile, ClusterIP Services only)
-
-
- This API may be extended in the future to support additional kinds of parent
- resources.
-
-
- The API object must be valid in the cluster; the Group and Kind must
- be registered in the cluster for this reference to be valid.
- properties:
- group:
- default: gateway.networking.k8s.io
- description: |-
- Group is the group of the referent.
- When unspecified, "gateway.networking.k8s.io" is inferred.
- To set the core API group (such as for a "Service" kind referent),
- Group must be explicitly set to "" (empty string).
-
-
- Support: Core
- maxLength: 253
- pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- kind:
- default: Gateway
- description: |-
- Kind is kind of the referent.
-
-
- There are two kinds of parent resources with "Core" support:
-
-
- * Gateway (Gateway conformance profile)
- * Service (Mesh conformance profile, ClusterIP Services only)
-
-
- Support for other resources is Implementation-Specific.
- maxLength: 63
- minLength: 1
- pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
- type: string
- name:
- description: |-
- Name is the name of the referent.
-
-
- Support: Core
- maxLength: 253
- minLength: 1
- type: string
- namespace:
- description: |-
- Namespace is the namespace of the referent. When unspecified, this refers
- to the local namespace of the Route.
-
-
- Note that there are specific rules for ParentRefs which cross namespace
- boundaries. Cross-namespace references are only valid if they are explicitly
- allowed by something in the namespace they are referring to. For example:
- Gateway has the AllowedRoutes field, and ReferenceGrant provides a
- generic way to enable any other kind of cross-namespace reference.
-
-
-
- ParentRefs from a Route to a Service in the same namespace are "producer"
- routes, which apply default routing rules to inbound connections from
- any namespace to the Service.
-
-
- ParentRefs from a Route to a Service in a different namespace are
- "consumer" routes, and these routing rules are only applied to outbound
- connections originating from the same namespace as the Route, for which
- the intended destination of the connections are a Service targeted as a
- ParentRef of the Route.
-
-
-
- Support: Core
- maxLength: 63
- minLength: 1
- pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
- type: string
- port:
- description: |-
- Port is the network port this Route targets. It can be interpreted
- differently based on the type of parent resource.
-
-
- When the parent resource is a Gateway, this targets all listeners
- listening on the specified port that also support this kind of Route(and
- select this Route). It's not recommended to set `Port` unless the
- networking behaviors specified in a Route must apply to a specific port
- as opposed to a listener(s) whose port(s) may be changed. When both Port
- and SectionName are specified, the name and port of the selected listener
- must match both specified values.
-
-
-
- When the parent resource is a Service, this targets a specific port in the
- Service spec. When both Port (experimental) and SectionName are specified,
- the name and port of the selected port must match both specified values.
-
-
-
- Implementations MAY choose to support other parent resources.
- Implementations supporting other types of parent resources MUST clearly
- document how/if Port is interpreted.
-
-
- For the purpose of status, an attachment is considered successful as
- long as the parent resource accepts it partially. For example, Gateway
- listeners can restrict which Routes can attach to them by Route kind,
- namespace, or hostname. If 1 of 2 Gateway listeners accept attachment
- from the referencing Route, the Route MUST be considered successfully
- attached. If no Gateway listeners accept attachment from this Route,
- the Route MUST be considered detached from the Gateway.
-
-
- Support: Extended
- format: int32
- maximum: 65535
- minimum: 1
- type: integer
- sectionName:
- description: |-
- SectionName is the name of a section within the target resource. In the
- following resources, SectionName is interpreted as the following:
-
-
- * Gateway: Listener name. When both Port (experimental) and SectionName
- are specified, the name and port of the selected listener must match
- both specified values.
- * Service: Port name. When both Port (experimental) and SectionName
- are specified, the name and port of the selected listener must match
- both specified values.
-
-
- Implementations MAY choose to support attaching Routes to other resources.
- If that is the case, they MUST clearly document how SectionName is
- interpreted.
-
-
- When unspecified (empty string), this will reference the entire resource.
- For the purpose of status, an attachment is considered successful if at
- least one section in the parent resource accepts it. For example, Gateway
- listeners can restrict which Routes can attach to them by Route kind,
- namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from
- the referencing Route, the Route MUST be considered successfully
- attached. If no Gateway listeners accept attachment from this Route, the
- Route MUST be considered detached from the Gateway.
-
-
- Support: Core
- maxLength: 253
- minLength: 1
- pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- required:
- - name
- type: object
- maxItems: 32
- type: array
- x-kubernetes-validations:
- - message: sectionName or port must be specified when parentRefs includes
- 2 or more references to the same parent
- rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind
- == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)
- || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__
- == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&
- p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName)
- || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName
- == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port)
- || p2.port == 0)): true))'
- - message: sectionName or port must be unique when parentRefs includes
- 2 or more references to the same parent
- rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind
- == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)
- || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__
- == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&
- p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)
- || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName
- == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName
- == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port)
- || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port
- == p2.port))))
- rules:
- description: Rules are a list of GRPC matchers, filters and actions.
- items:
- description: |-
- GRPCRouteRule defines the semantics for matching a gRPC request based on
- conditions (matches), processing it (filters), and forwarding the request to
- an API object (backendRefs).
- properties:
- backendRefs:
- description: |-
- BackendRefs defines the backend(s) where matching requests should be
- sent.
-
-
- Failure behavior here depends on how many BackendRefs are specified and
- how many are invalid.
-
-
- If *all* entries in BackendRefs are invalid, and there are also no filters
- specified in this route rule, *all* traffic which matches this rule MUST
- receive an `UNAVAILABLE` status.
-
-
- See the GRPCBackendRef definition for the rules about what makes a single
- GRPCBackendRef invalid.
-
-
- When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for
- requests that would have otherwise been routed to an invalid backend. If
- multiple backends are specified, and some are invalid, the proportion of
- requests that would otherwise have been routed to an invalid backend
- MUST receive an `UNAVAILABLE` status.
-
-
- For example, if two backends are specified with equal weights, and one is
- invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status.
- Implementations may choose how that 50 percent is determined.
-
-
- Support: Core for Kubernetes Service
-
-
- Support: Implementation-specific for any other resource
-
-
- Support for weight: Core
- items:
- description: |-
- GRPCBackendRef defines how a GRPCRoute forwards a gRPC request.
-
-
- Note that when a namespace different than the local namespace is specified, a
- ReferenceGrant object is required in the referent namespace to allow that
- namespace's owner to accept the reference. See the ReferenceGrant
- documentation for details.
-
-
-
-
-
- When the BackendRef points to a Kubernetes Service, implementations SHOULD
- honor the appProtocol field if it is set for the target Service Port.
-
-
- Implementations supporting appProtocol SHOULD recognize the Kubernetes
- Standard Application Protocols defined in KEP-3726.
-
-
- If a Service appProtocol isn't specified, an implementation MAY infer the
- backend protocol through its own means. Implementations MAY infer the
- protocol from the Route type referring to the backend Service.
-
-
- If a Route is not able to send traffic to the backend using the specified
- protocol then the backend is considered invalid. Implementations MUST set the
- "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason.
-
-
-
- properties:
- filters:
- description: |-
- Filters defined at this level MUST be executed if and only if the
- request is being forwarded to the backend defined here.
-
-
- Support: Implementation-specific (For broader support of filters, use the
- Filters field in GRPCRouteRule.)
- items:
- description: |-
- GRPCRouteFilter defines processing steps that must be completed during the
- request or response lifecycle. GRPCRouteFilters are meant as an extension
- point to express processing that may be done in Gateway implementations. Some
- examples include request or response modification, implementing
- authentication strategies, rate-limiting, and traffic shaping. API
- guarantee/conformance is defined based on the type of the filter.
- properties:
- extensionRef:
- description: |-
- ExtensionRef is an optional, implementation-specific extension to the
- "filter" behavior. For example, resource "myroutefilter" in group
- "networking.example.net"). ExtensionRef MUST NOT be used for core and
- extended filters.
-
-
- Support: Implementation-specific
-
-
- This filter can be used multiple times within the same rule.
- properties:
- group:
- description: |-
- Group is the group of the referent. For example, "gateway.networking.k8s.io".
- When unspecified or empty string, core API group is inferred.
- maxLength: 253
- pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- kind:
- description: Kind is kind of the referent. For
- example "HTTPRoute" or "Service".
- maxLength: 63
- minLength: 1
- pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
- type: string
- name:
- description: Name is the name of the referent.
- maxLength: 253
- minLength: 1
- type: string
- required:
- - group
- - kind
- - name
- type: object
- requestHeaderModifier:
- description: |-
- RequestHeaderModifier defines a schema for a filter that modifies request
- headers.
-
-
- Support: Core
- properties:
- add:
- description: |-
- Add adds the given header(s) (name, value) to the request
- before the action. It appends to any existing values associated
- with the header name.
-
-
- Input:
- GET /foo HTTP/1.1
- my-header: foo
-
-
- Config:
- add:
- - name: "my-header"
- value: "bar,baz"
-
-
- Output:
- GET /foo HTTP/1.1
- my-header: foo,bar,baz
- items:
- description: HTTPHeader represents an HTTP
- Header name and value as defined by RFC
- 7230.
- properties:
- name:
- description: |-
- Name is the name of the HTTP Header to be matched. Name matching MUST be
- case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
-
- If multiple entries specify equivalent header names, the first entry with
- an equivalent name MUST be considered for a match. Subsequent entries
- with an equivalent header name MUST be ignored. Due to the
- case-insensitivity of header names, "foo" and "Foo" are considered
- equivalent.
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
- type: string
- value:
- description: Value is the value of HTTP
- Header to be matched.
- maxLength: 4096
- minLength: 1
- type: string
- required:
- - name
- - value
- type: object
- maxItems: 16
- type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
- remove:
- description: |-
- Remove the given header(s) from the HTTP request before the action. The
- value of Remove is a list of HTTP header names. Note that the header
- names are case-insensitive (see
- https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
-
- Input:
- GET /foo HTTP/1.1
- my-header1: foo
- my-header2: bar
- my-header3: baz
-
-
- Config:
- remove: ["my-header1", "my-header3"]
-
-
- Output:
- GET /foo HTTP/1.1
- my-header2: bar
- items:
- type: string
- maxItems: 16
- type: array
- x-kubernetes-list-type: set
- set:
- description: |-
- Set overwrites the request with the given header (name, value)
- before the action.
-
-
- Input:
- GET /foo HTTP/1.1
- my-header: foo
-
-
- Config:
- set:
- - name: "my-header"
- value: "bar"
-
-
- Output:
- GET /foo HTTP/1.1
- my-header: bar
- items:
- description: HTTPHeader represents an HTTP
- Header name and value as defined by RFC
- 7230.
- properties:
- name:
- description: |-
- Name is the name of the HTTP Header to be matched. Name matching MUST be
- case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
-
- If multiple entries specify equivalent header names, the first entry with
- an equivalent name MUST be considered for a match. Subsequent entries
- with an equivalent header name MUST be ignored. Due to the
- case-insensitivity of header names, "foo" and "Foo" are considered
- equivalent.
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
- type: string
- value:
- description: Value is the value of HTTP
- Header to be matched.
- maxLength: 4096
- minLength: 1
- type: string
- required:
- - name
- - value
- type: object
- maxItems: 16
- type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
- type: object
- requestMirror:
- description: |-
- RequestMirror defines a schema for a filter that mirrors requests.
- Requests are sent to the specified destination, but responses from
- that destination are ignored.
-
-
- This filter can be used multiple times within the same rule. Note that
- not all implementations will be able to support mirroring to multiple
- backends.
-
-
- Support: Extended
- properties:
- backendRef:
- description: |-
- BackendRef references a resource where mirrored requests are sent.
-
-
- Mirrored requests must be sent only to a single destination endpoint
- within this BackendRef, irrespective of how many endpoints are present
- within this BackendRef.
-
-
- If the referent cannot be found, this BackendRef is invalid and must be
- dropped from the Gateway. The controller must ensure the "ResolvedRefs"
- condition on the Route status is set to `status: False` and not configure
- this backend in the underlying implementation.
-
-
- If there is a cross-namespace reference to an *existing* object
- that is not allowed by a ReferenceGrant, the controller must ensure the
- "ResolvedRefs" condition on the Route is set to `status: False`,
- with the "RefNotPermitted" reason and not configure this backend in the
- underlying implementation.
-
-
- In either error case, the Message of the `ResolvedRefs` Condition
- should be used to provide more detail about the problem.
-
-
- Support: Extended for Kubernetes Service
-
-
- Support: Implementation-specific for any other resource
- properties:
- group:
- default: ""
- description: |-
- Group is the group of the referent. For example, "gateway.networking.k8s.io".
- When unspecified or empty string, core API group is inferred.
- maxLength: 253
- pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- kind:
- default: Service
- description: |-
- Kind is the Kubernetes resource kind of the referent. For example
- "Service".
-
-
- Defaults to "Service" when not specified.
-
-
- ExternalName services can refer to CNAME DNS records that may live
- outside of the cluster and as such are difficult to reason about in
- terms of conformance. They also may not be safe to forward to (see
- CVE-2021-25740 for more information). Implementations SHOULD NOT
- support ExternalName Services.
-
-
- Support: Core (Services with a type other than ExternalName)
-
-
- Support: Implementation-specific (Services with type ExternalName)
- maxLength: 63
- minLength: 1
- pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
- type: string
- name:
- description: Name is the name of the referent.
- maxLength: 253
- minLength: 1
- type: string
- namespace:
- description: |-
- Namespace is the namespace of the backend. When unspecified, the local
- namespace is inferred.
-
-
- Note that when a namespace different than the local namespace is specified,
- a ReferenceGrant object is required in the referent namespace to allow that
- namespace's owner to accept the reference. See the ReferenceGrant
- documentation for details.
-
-
- Support: Core
- maxLength: 63
- minLength: 1
- pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
- type: string
- port:
- description: |-
- Port specifies the destination port number to use for this resource.
- Port is required when the referent is a Kubernetes Service. In this
- case, the port number is the service port number, not the target port.
- For other resources, destination port might be derived from the referent
- resource or this field.
- format: int32
- maximum: 65535
- minimum: 1
- type: integer
- required:
- - name
- type: object
- x-kubernetes-validations:
- - message: Must have port for Service reference
- rule: '(size(self.group) == 0 && self.kind
- == ''Service'') ? has(self.port) : true'
- required:
- - backendRef
- type: object
- responseHeaderModifier:
- description: |-
- ResponseHeaderModifier defines a schema for a filter that modifies response
- headers.
-
-
- Support: Extended
- properties:
- add:
- description: |-
- Add adds the given header(s) (name, value) to the request
- before the action. It appends to any existing values associated
- with the header name.
-
-
- Input:
- GET /foo HTTP/1.1
- my-header: foo
-
-
- Config:
- add:
- - name: "my-header"
- value: "bar,baz"
-
-
- Output:
- GET /foo HTTP/1.1
- my-header: foo,bar,baz
- items:
- description: HTTPHeader represents an HTTP
- Header name and value as defined by RFC
- 7230.
- properties:
- name:
- description: |-
- Name is the name of the HTTP Header to be matched. Name matching MUST be
- case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
-
- If multiple entries specify equivalent header names, the first entry with
- an equivalent name MUST be considered for a match. Subsequent entries
- with an equivalent header name MUST be ignored. Due to the
- case-insensitivity of header names, "foo" and "Foo" are considered
- equivalent.
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
- type: string
- value:
- description: Value is the value of HTTP
- Header to be matched.
- maxLength: 4096
- minLength: 1
- type: string
- required:
- - name
- - value
- type: object
- maxItems: 16
- type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
- remove:
- description: |-
- Remove the given header(s) from the HTTP request before the action. The
- value of Remove is a list of HTTP header names. Note that the header
- names are case-insensitive (see
- https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
-
- Input:
- GET /foo HTTP/1.1
- my-header1: foo
- my-header2: bar
- my-header3: baz
-
-
- Config:
- remove: ["my-header1", "my-header3"]
-
-
- Output:
- GET /foo HTTP/1.1
- my-header2: bar
- items:
- type: string
- maxItems: 16
- type: array
- x-kubernetes-list-type: set
- set:
- description: |-
- Set overwrites the request with the given header (name, value)
- before the action.
-
-
- Input:
- GET /foo HTTP/1.1
- my-header: foo
-
-
- Config:
- set:
- - name: "my-header"
- value: "bar"
-
-
- Output:
- GET /foo HTTP/1.1
- my-header: bar
- items:
- description: HTTPHeader represents an HTTP
- Header name and value as defined by RFC
- 7230.
- properties:
- name:
- description: |-
- Name is the name of the HTTP Header to be matched. Name matching MUST be
- case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
-
- If multiple entries specify equivalent header names, the first entry with
- an equivalent name MUST be considered for a match. Subsequent entries
- with an equivalent header name MUST be ignored. Due to the
- case-insensitivity of header names, "foo" and "Foo" are considered
- equivalent.
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
- type: string
- value:
- description: Value is the value of HTTP
- Header to be matched.
- maxLength: 4096
- minLength: 1
- type: string
- required:
- - name
- - value
- type: object
- maxItems: 16
- type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
- type: object
- type:
- description: |+
- Type identifies the type of filter to apply. As with other API fields,
- types are classified into three conformance levels:
-
-
- - Core: Filter types and their corresponding configuration defined by
- "Support: Core" in this package, e.g. "RequestHeaderModifier". All
- implementations supporting GRPCRoute MUST support core filters.
-
-
- - Extended: Filter types and their corresponding configuration defined by
- "Support: Extended" in this package, e.g. "RequestMirror". Implementers
- are encouraged to support extended filters.
-
-
- - Implementation-specific: Filters that are defined and supported by specific vendors.
- In the future, filters showing convergence in behavior across multiple
- implementations will be considered for inclusion in extended or core
- conformance levels. Filter-specific configuration for such filters
- is specified using the ExtensionRef field. `Type` MUST be set to
- "ExtensionRef" for custom filters.
-
-
- Implementers are encouraged to define custom implementation types to
- extend the core API with implementation-specific behavior.
-
-
- If a reference to a custom filter type cannot be resolved, the filter
- MUST NOT be skipped. Instead, requests that would have been processed by
- that filter MUST receive a HTTP error response.
-
-
- enum:
- - ResponseHeaderModifier
- - RequestHeaderModifier
- - RequestMirror
- - ExtensionRef
- type: string
- required:
- - type
- type: object
- x-kubernetes-validations:
- - message: filter.requestHeaderModifier must be nil
- if the filter.type is not RequestHeaderModifier
- rule: '!(has(self.requestHeaderModifier) && self.type
- != ''RequestHeaderModifier'')'
- - message: filter.requestHeaderModifier must be specified
- for RequestHeaderModifier filter.type
- rule: '!(!has(self.requestHeaderModifier) && self.type
- == ''RequestHeaderModifier'')'
- - message: filter.responseHeaderModifier must be nil
- if the filter.type is not ResponseHeaderModifier
- rule: '!(has(self.responseHeaderModifier) && self.type
- != ''ResponseHeaderModifier'')'
- - message: filter.responseHeaderModifier must be specified
- for ResponseHeaderModifier filter.type
- rule: '!(!has(self.responseHeaderModifier) && self.type
- == ''ResponseHeaderModifier'')'
- - message: filter.requestMirror must be nil if the filter.type
- is not RequestMirror
- rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'
- - message: filter.requestMirror must be specified for
- RequestMirror filter.type
- rule: '!(!has(self.requestMirror) && self.type ==
- ''RequestMirror'')'
- - message: filter.extensionRef must be nil if the filter.type
- is not ExtensionRef
- rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'
- - message: filter.extensionRef must be specified for
- ExtensionRef filter.type
- rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
- maxItems: 16
- type: array
- x-kubernetes-validations:
- - message: RequestHeaderModifier filter cannot be repeated
- rule: self.filter(f, f.type == 'RequestHeaderModifier').size()
- <= 1
- - message: ResponseHeaderModifier filter cannot be repeated
- rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()
- <= 1
- group:
- default: ""
- description: |-
- Group is the group of the referent. For example, "gateway.networking.k8s.io".
- When unspecified or empty string, core API group is inferred.
- maxLength: 253
- pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- kind:
- default: Service
- description: |-
- Kind is the Kubernetes resource kind of the referent. For example
- "Service".
-
-
- Defaults to "Service" when not specified.
-
-
- ExternalName services can refer to CNAME DNS records that may live
- outside of the cluster and as such are difficult to reason about in
- terms of conformance. They also may not be safe to forward to (see
- CVE-2021-25740 for more information). Implementations SHOULD NOT
- support ExternalName Services.
-
-
- Support: Core (Services with a type other than ExternalName)
-
-
- Support: Implementation-specific (Services with type ExternalName)
- maxLength: 63
- minLength: 1
- pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
- type: string
- name:
- description: Name is the name of the referent.
- maxLength: 253
- minLength: 1
- type: string
- namespace:
- description: |-
- Namespace is the namespace of the backend. When unspecified, the local
- namespace is inferred.
-
-
- Note that when a namespace different than the local namespace is specified,
- a ReferenceGrant object is required in the referent namespace to allow that
- namespace's owner to accept the reference. See the ReferenceGrant
- documentation for details.
-
-
- Support: Core
- maxLength: 63
- minLength: 1
- pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
- type: string
- port:
- description: |-
- Port specifies the destination port number to use for this resource.
- Port is required when the referent is a Kubernetes Service. In this
- case, the port number is the service port number, not the target port.
- For other resources, destination port might be derived from the referent
- resource or this field.
- format: int32
- maximum: 65535
- minimum: 1
- type: integer
- weight:
- default: 1
- description: |-
- Weight specifies the proportion of requests forwarded to the referenced
- backend. This is computed as weight/(sum of all weights in this
- BackendRefs list). For non-zero values, there may be some epsilon from
- the exact proportion defined here depending on the precision an
- implementation supports. Weight is not a percentage and the sum of
- weights does not need to equal 100.
-
-
- If only one backend is specified and it has a weight greater than 0, 100%
- of the traffic is forwarded to that backend. If weight is set to 0, no
- traffic should be forwarded for this entry. If unspecified, weight
- defaults to 1.
-
-
- Support for this field varies based on the context where used.
- format: int32
- maximum: 1000000
- minimum: 0
- type: integer
- required:
- - name
- type: object
- x-kubernetes-validations:
- - message: Must have port for Service reference
- rule: '(size(self.group) == 0 && self.kind == ''Service'')
- ? has(self.port) : true'
- maxItems: 16
- type: array
- filters:
- description: |-
- Filters define the filters that are applied to requests that match
- this rule.
-
-
- The effects of ordering of multiple behaviors are currently unspecified.
- This can change in the future based on feedback during the alpha stage.
-
-
- Conformance-levels at this level are defined based on the type of filter:
-
-
- - ALL core filters MUST be supported by all implementations that support
- GRPCRoute.
- - Implementers are encouraged to support extended filters.
- - Implementation-specific custom filters have no API guarantees across
- implementations.
-
-
- Specifying the same filter multiple times is not supported unless explicitly
- indicated in the filter.
-
-
- If an implementation can not support a combination of filters, it must clearly
- document that limitation. In cases where incompatible or unsupported
- filters are specified and cause the `Accepted` condition to be set to status
- `False`, implementations may use the `IncompatibleFilters` reason to specify
- this configuration error.
-
-
- Support: Core
- items:
- description: |-
- GRPCRouteFilter defines processing steps that must be completed during the
- request or response lifecycle. GRPCRouteFilters are meant as an extension
- point to express processing that may be done in Gateway implementations. Some
- examples include request or response modification, implementing
- authentication strategies, rate-limiting, and traffic shaping. API
- guarantee/conformance is defined based on the type of the filter.
- properties:
- extensionRef:
- description: |-
- ExtensionRef is an optional, implementation-specific extension to the
- "filter" behavior. For example, resource "myroutefilter" in group
- "networking.example.net"). ExtensionRef MUST NOT be used for core and
- extended filters.
-
-
- Support: Implementation-specific
-
-
- This filter can be used multiple times within the same rule.
- properties:
- group:
- description: |-
- Group is the group of the referent. For example, "gateway.networking.k8s.io".
- When unspecified or empty string, core API group is inferred.
- maxLength: 253
- pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- kind:
- description: Kind is kind of the referent. For example
- "HTTPRoute" or "Service".
- maxLength: 63
- minLength: 1
- pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
- type: string
- name:
- description: Name is the name of the referent.
- maxLength: 253
- minLength: 1
- type: string
- required:
- - group
- - kind
- - name
- type: object
- requestHeaderModifier:
- description: |-
- RequestHeaderModifier defines a schema for a filter that modifies request
- headers.
-
-
- Support: Core
- properties:
- add:
- description: |-
- Add adds the given header(s) (name, value) to the request
- before the action. It appends to any existing values associated
- with the header name.
-
-
- Input:
- GET /foo HTTP/1.1
- my-header: foo
-
-
- Config:
- add:
- - name: "my-header"
- value: "bar,baz"
-
-
- Output:
- GET /foo HTTP/1.1
- my-header: foo,bar,baz
- items:
- description: HTTPHeader represents an HTTP Header
- name and value as defined by RFC 7230.
- properties:
- name:
- description: |-
- Name is the name of the HTTP Header to be matched. Name matching MUST be
- case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
-
- If multiple entries specify equivalent header names, the first entry with
- an equivalent name MUST be considered for a match. Subsequent entries
- with an equivalent header name MUST be ignored. Due to the
- case-insensitivity of header names, "foo" and "Foo" are considered
- equivalent.
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
- type: string
- value:
- description: Value is the value of HTTP Header
- to be matched.
- maxLength: 4096
- minLength: 1
- type: string
- required:
- - name
- - value
- type: object
- maxItems: 16
- type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
- remove:
- description: |-
- Remove the given header(s) from the HTTP request before the action. The
- value of Remove is a list of HTTP header names. Note that the header
- names are case-insensitive (see
- https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
-
- Input:
- GET /foo HTTP/1.1
- my-header1: foo
- my-header2: bar
- my-header3: baz
-
-
- Config:
- remove: ["my-header1", "my-header3"]
-
-
- Output:
- GET /foo HTTP/1.1
- my-header2: bar
- items:
- type: string
- maxItems: 16
- type: array
- x-kubernetes-list-type: set
- set:
- description: |-
- Set overwrites the request with the given header (name, value)
- before the action.
-
-
- Input:
- GET /foo HTTP/1.1
- my-header: foo
-
-
- Config:
- set:
- - name: "my-header"
- value: "bar"
-
-
- Output:
- GET /foo HTTP/1.1
- my-header: bar
- items:
- description: HTTPHeader represents an HTTP Header
- name and value as defined by RFC 7230.
- properties:
- name:
- description: |-
- Name is the name of the HTTP Header to be matched. Name matching MUST be
- case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
-
- If multiple entries specify equivalent header names, the first entry with
- an equivalent name MUST be considered for a match. Subsequent entries
- with an equivalent header name MUST be ignored. Due to the
- case-insensitivity of header names, "foo" and "Foo" are considered
- equivalent.
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
- type: string
- value:
- description: Value is the value of HTTP Header
- to be matched.
- maxLength: 4096
- minLength: 1
- type: string
- required:
- - name
- - value
- type: object
- maxItems: 16
- type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
- type: object
- requestMirror:
- description: |-
- RequestMirror defines a schema for a filter that mirrors requests.
- Requests are sent to the specified destination, but responses from
- that destination are ignored.
-
-
- This filter can be used multiple times within the same rule. Note that
- not all implementations will be able to support mirroring to multiple
- backends.
-
-
- Support: Extended
- properties:
- backendRef:
- description: |-
- BackendRef references a resource where mirrored requests are sent.
-
-
- Mirrored requests must be sent only to a single destination endpoint
- within this BackendRef, irrespective of how many endpoints are present
- within this BackendRef.
-
-
- If the referent cannot be found, this BackendRef is invalid and must be
- dropped from the Gateway. The controller must ensure the "ResolvedRefs"
- condition on the Route status is set to `status: False` and not configure
- this backend in the underlying implementation.
-
-
- If there is a cross-namespace reference to an *existing* object
- that is not allowed by a ReferenceGrant, the controller must ensure the
- "ResolvedRefs" condition on the Route is set to `status: False`,
- with the "RefNotPermitted" reason and not configure this backend in the
- underlying implementation.
-
-
- In either error case, the Message of the `ResolvedRefs` Condition
- should be used to provide more detail about the problem.
-
-
- Support: Extended for Kubernetes Service
-
-
- Support: Implementation-specific for any other resource
- properties:
- group:
- default: ""
- description: |-
- Group is the group of the referent. For example, "gateway.networking.k8s.io".
- When unspecified or empty string, core API group is inferred.
- maxLength: 253
- pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- kind:
- default: Service
- description: |-
- Kind is the Kubernetes resource kind of the referent. For example
- "Service".
-
-
- Defaults to "Service" when not specified.
-
-
- ExternalName services can refer to CNAME DNS records that may live
- outside of the cluster and as such are difficult to reason about in
- terms of conformance. They also may not be safe to forward to (see
- CVE-2021-25740 for more information). Implementations SHOULD NOT
- support ExternalName Services.
-
-
- Support: Core (Services with a type other than ExternalName)
-
-
- Support: Implementation-specific (Services with type ExternalName)
- maxLength: 63
- minLength: 1
- pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
- type: string
- name:
- description: Name is the name of the referent.
- maxLength: 253
- minLength: 1
- type: string
- namespace:
- description: |-
- Namespace is the namespace of the backend. When unspecified, the local
- namespace is inferred.
-
-
- Note that when a namespace different than the local namespace is specified,
- a ReferenceGrant object is required in the referent namespace to allow that
- namespace's owner to accept the reference. See the ReferenceGrant
- documentation for details.
-
-
- Support: Core
- maxLength: 63
- minLength: 1
- pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
- type: string
- port:
- description: |-
- Port specifies the destination port number to use for this resource.
- Port is required when the referent is a Kubernetes Service. In this
- case, the port number is the service port number, not the target port.
- For other resources, destination port might be derived from the referent
- resource or this field.
- format: int32
- maximum: 65535
- minimum: 1
- type: integer
- required:
- - name
- type: object
- x-kubernetes-validations:
- - message: Must have port for Service reference
- rule: '(size(self.group) == 0 && self.kind == ''Service'')
- ? has(self.port) : true'
- required:
- - backendRef
- type: object
- responseHeaderModifier:
- description: |-
- ResponseHeaderModifier defines a schema for a filter that modifies response
- headers.
-
-
- Support: Extended
- properties:
- add:
- description: |-
- Add adds the given header(s) (name, value) to the request
- before the action. It appends to any existing values associated
- with the header name.
-
-
- Input:
- GET /foo HTTP/1.1
- my-header: foo
-
-
- Config:
- add:
- - name: "my-header"
- value: "bar,baz"
-
-
- Output:
- GET /foo HTTP/1.1
- my-header: foo,bar,baz
- items:
- description: HTTPHeader represents an HTTP Header
- name and value as defined by RFC 7230.
- properties:
- name:
- description: |-
- Name is the name of the HTTP Header to be matched. Name matching MUST be
- case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
-
- If multiple entries specify equivalent header names, the first entry with
- an equivalent name MUST be considered for a match. Subsequent entries
- with an equivalent header name MUST be ignored. Due to the
- case-insensitivity of header names, "foo" and "Foo" are considered
- equivalent.
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
- type: string
- value:
- description: Value is the value of HTTP Header
- to be matched.
- maxLength: 4096
- minLength: 1
- type: string
- required:
- - name
- - value
- type: object
- maxItems: 16
- type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
- remove:
- description: |-
- Remove the given header(s) from the HTTP request before the action. The
- value of Remove is a list of HTTP header names. Note that the header
- names are case-insensitive (see
- https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
-
- Input:
- GET /foo HTTP/1.1
- my-header1: foo
- my-header2: bar
- my-header3: baz
-
-
- Config:
- remove: ["my-header1", "my-header3"]
-
-
- Output:
- GET /foo HTTP/1.1
- my-header2: bar
- items:
- type: string
- maxItems: 16
- type: array
- x-kubernetes-list-type: set
- set:
- description: |-
- Set overwrites the request with the given header (name, value)
- before the action.
-
-
- Input:
- GET /foo HTTP/1.1
- my-header: foo
-
-
- Config:
- set:
- - name: "my-header"
- value: "bar"
-
-
- Output:
- GET /foo HTTP/1.1
- my-header: bar
- items:
- description: HTTPHeader represents an HTTP Header
- name and value as defined by RFC 7230.
- properties:
- name:
- description: |-
- Name is the name of the HTTP Header to be matched. Name matching MUST be
- case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
-
- If multiple entries specify equivalent header names, the first entry with
- an equivalent name MUST be considered for a match. Subsequent entries
- with an equivalent header name MUST be ignored. Due to the
- case-insensitivity of header names, "foo" and "Foo" are considered
- equivalent.
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
- type: string
- value:
- description: Value is the value of HTTP Header
- to be matched.
- maxLength: 4096
- minLength: 1
- type: string
- required:
- - name
- - value
- type: object
- maxItems: 16
- type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
- type: object
- type:
- description: |+
- Type identifies the type of filter to apply. As with other API fields,
- types are classified into three conformance levels:
-
-
- - Core: Filter types and their corresponding configuration defined by
- "Support: Core" in this package, e.g. "RequestHeaderModifier". All
- implementations supporting GRPCRoute MUST support core filters.
-
-
- - Extended: Filter types and their corresponding configuration defined by
- "Support: Extended" in this package, e.g. "RequestMirror". Implementers
- are encouraged to support extended filters.
-
-
- - Implementation-specific: Filters that are defined and supported by specific vendors.
- In the future, filters showing convergence in behavior across multiple
- implementations will be considered for inclusion in extended or core
- conformance levels. Filter-specific configuration for such filters
- is specified using the ExtensionRef field. `Type` MUST be set to
- "ExtensionRef" for custom filters.
-
-
- Implementers are encouraged to define custom implementation types to
- extend the core API with implementation-specific behavior.
-
-
- If a reference to a custom filter type cannot be resolved, the filter
- MUST NOT be skipped. Instead, requests that would have been processed by
- that filter MUST receive a HTTP error response.
-
-
- enum:
- - ResponseHeaderModifier
- - RequestHeaderModifier
- - RequestMirror
- - ExtensionRef
- type: string
- required:
- - type
- type: object
- x-kubernetes-validations:
- - message: filter.requestHeaderModifier must be nil if the
- filter.type is not RequestHeaderModifier
- rule: '!(has(self.requestHeaderModifier) && self.type !=
- ''RequestHeaderModifier'')'
- - message: filter.requestHeaderModifier must be specified
- for RequestHeaderModifier filter.type
- rule: '!(!has(self.requestHeaderModifier) && self.type ==
- ''RequestHeaderModifier'')'
- - message: filter.responseHeaderModifier must be nil if the
- filter.type is not ResponseHeaderModifier
- rule: '!(has(self.responseHeaderModifier) && self.type !=
- ''ResponseHeaderModifier'')'
- - message: filter.responseHeaderModifier must be specified
- for ResponseHeaderModifier filter.type
- rule: '!(!has(self.responseHeaderModifier) && self.type
- == ''ResponseHeaderModifier'')'
- - message: filter.requestMirror must be nil if the filter.type
- is not RequestMirror
- rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'
- - message: filter.requestMirror must be specified for RequestMirror
- filter.type
- rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')'
- - message: filter.extensionRef must be nil if the filter.type
- is not ExtensionRef
- rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'
- - message: filter.extensionRef must be specified for ExtensionRef
- filter.type
- rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
- maxItems: 16
- type: array
- x-kubernetes-validations:
- - message: RequestHeaderModifier filter cannot be repeated
- rule: self.filter(f, f.type == 'RequestHeaderModifier').size()
- <= 1
- - message: ResponseHeaderModifier filter cannot be repeated
- rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()
- <= 1
- matches:
- description: |-
- Matches define conditions used for matching the rule against incoming
- gRPC requests. Each match is independent, i.e. this rule will be matched
- if **any** one of the matches is satisfied.
-
-
- For example, take the following matches configuration:
-
-
- ```
- matches:
- - method:
- service: foo.bar
- headers:
- values:
- version: 2
- - method:
- service: foo.bar.v2
- ```
-
-
- For a request to match against this rule, it MUST satisfy
- EITHER of the two conditions:
-
-
- - service of foo.bar AND contains the header `version: 2`
- - service of foo.bar.v2
-
-
- See the documentation for GRPCRouteMatch on how to specify multiple
- match conditions to be ANDed together.
-
-
- If no matches are specified, the implementation MUST match every gRPC request.
-
-
- Proxy or Load Balancer routing configuration generated from GRPCRoutes
- MUST prioritize rules based on the following criteria, continuing on
- ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes.
- Precedence MUST be given to the rule with the largest number of:
-
-
- * Characters in a matching non-wildcard hostname.
- * Characters in a matching hostname.
- * Characters in a matching service.
- * Characters in a matching method.
- * Header matches.
-
-
- If ties still exist across multiple Routes, matching precedence MUST be
- determined in order of the following criteria, continuing on ties:
-
-
- * The oldest Route based on creation timestamp.
- * The Route appearing first in alphabetical order by
- "{namespace}/{name}".
-
-
- If ties still exist within the Route that has been given precedence,
- matching precedence MUST be granted to the first matching rule meeting
- the above criteria.
- items:
- description: |-
- GRPCRouteMatch defines the predicate used to match requests to a given
- action. Multiple match types are ANDed together, i.e. the match will
- evaluate to true only if all conditions are satisfied.
-
-
- For example, the match below will match a gRPC request only if its service
- is `foo` AND it contains the `version: v1` header:
-
-
- ```
- matches:
- - method:
- type: Exact
- service: "foo"
- headers:
- - name: "version"
- value "v1"
-
-
- ```
- properties:
- headers:
- description: |-
- Headers specifies gRPC request header matchers. Multiple match values are
- ANDed together, meaning, a request MUST match all the specified headers
- to select the route.
- items:
- description: |-
- GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request
- headers.
- properties:
- name:
- description: |-
- Name is the name of the gRPC Header to be matched.
-
-
- If multiple entries specify equivalent header names, only the first
- entry with an equivalent name MUST be considered for a match. Subsequent
- entries with an equivalent header name MUST be ignored. Due to the
- case-insensitivity of header names, "foo" and "Foo" are considered
- equivalent.
- maxLength: 256
- minLength: 1
- pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
- type: string
- type:
- default: Exact
- description: Type specifies how to match against
- the value of the header.
- enum:
- - Exact
- - RegularExpression
- type: string
- value:
- description: Value is the value of the gRPC Header
- to be matched.
- maxLength: 4096
- minLength: 1
- type: string
- required:
- - name
- - value
- type: object
- maxItems: 16
- type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
- method:
- description: |-
- Method specifies a gRPC request service/method matcher. If this field is
- not specified, all services and methods will match.
- properties:
- method:
- description: |-
- Value of the method to match against. If left empty or omitted, will
- match all services.
-
-
- At least one of Service and Method MUST be a non-empty string.
- maxLength: 1024
- type: string
- service:
- description: |-
- Value of the service to match against. If left empty or omitted, will
- match any service.
-
-
- At least one of Service and Method MUST be a non-empty string.
- maxLength: 1024
- type: string
- type:
- default: Exact
- description: |-
- Type specifies how to match against the service and/or method.
- Support: Core (Exact with service and method specified)
-
-
- Support: Implementation-specific (Exact with method specified but no service specified)
-
-
- Support: Implementation-specific (RegularExpression)
- enum:
- - Exact
- - RegularExpression
- type: string
- type: object
- x-kubernetes-validations:
- - message: One or both of 'service' or 'method' must be
- specified
- rule: 'has(self.type) ? has(self.service) || has(self.method)
- : true'
- - message: service must only contain valid characters
- (matching ^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$)
- rule: '(!has(self.type) || self.type == ''Exact'') &&
- has(self.service) ? self.service.matches(r"""^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$"""):
- true'
- - message: method must only contain valid characters (matching
- ^[A-Za-z_][A-Za-z_0-9]*$)
- rule: '(!has(self.type) || self.type == ''Exact'') &&
- has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""):
- true'
- type: object
- maxItems: 8
- type: array
- sessionPersistence:
- description: |+
- SessionPersistence defines and configures session persistence
- for the route rule.
-
-
- Support: Extended
-
-
- properties:
- absoluteTimeout:
- description: |-
- AbsoluteTimeout defines the absolute timeout of the persistent
- session. Once the AbsoluteTimeout duration has elapsed, the
- session becomes invalid.
-
-
- Support: Extended
- pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
- type: string
- cookieConfig:
- description: |-
- CookieConfig provides configuration settings that are specific
- to cookie-based session persistence.
-
-
- Support: Core
- properties:
- lifetimeType:
- default: Session
- description: |-
- LifetimeType specifies whether the cookie has a permanent or
- session-based lifetime. A permanent cookie persists until its
- specified expiry time, defined by the Expires or Max-Age cookie
- attributes, while a session cookie is deleted when the current
- session ends.
-
-
- When set to "Permanent", AbsoluteTimeout indicates the
- cookie's lifetime via the Expires or Max-Age cookie attributes
- and is required.
-
-
- When set to "Session", AbsoluteTimeout indicates the
- absolute lifetime of the cookie tracked by the gateway and
- is optional.
-
-
- Support: Core for "Session" type
-
-
- Support: Extended for "Permanent" type
- enum:
- - Permanent
- - Session
- type: string
- type: object
- idleTimeout:
- description: |-
- IdleTimeout defines the idle timeout of the persistent session.
- Once the session has been idle for more than the specified
- IdleTimeout duration, the session becomes invalid.
-
-
- Support: Extended
- pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
- type: string
- sessionName:
- description: |-
- SessionName defines the name of the persistent session token
- which may be reflected in the cookie or the header. Users
- should avoid reusing session names to prevent unintended
- consequences, such as rejection or unpredictable behavior.
-
-
- Support: Implementation-specific
- maxLength: 128
- type: string
- type:
- default: Cookie
- description: |-
- Type defines the type of session persistence such as through
- the use a header or cookie. Defaults to cookie based session
- persistence.
-
-
- Support: Core for "Cookie" type
-
-
- Support: Extended for "Header" type
- enum:
- - Cookie
- - Header
- type: string
- type: object
- x-kubernetes-validations:
- - message: AbsoluteTimeout must be specified when cookie lifetimeType
- is Permanent
- rule: '!has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType
- != ''Permanent'' || has(self.absoluteTimeout)'
- type: object
- maxItems: 16
- type: array
- type: object
- status:
- description: Status defines the current state of GRPCRoute.
- properties:
- parents:
- description: |-
- Parents is a list of parent resources (usually Gateways) that are
- associated with the route, and the status of the route with respect to
- each parent. When this route attaches to a parent, the controller that
- manages the parent must add an entry to this list when the controller
- first sees the route and should update the entry as appropriate when the
- route or gateway is modified.
-
-
- Note that parent references that cannot be resolved by an implementation
- of this API will not be added to this list. Implementations of this API
- can only populate Route status for the Gateways/parent resources they are
- responsible for.
-
-
- A maximum of 32 Gateways will be represented in this list. An empty list
- means the route has not been attached to any Gateway.
- items:
- description: |-
- RouteParentStatus describes the status of a route with respect to an
- associated Parent.
- properties:
- conditions:
- description: |-
- Conditions describes the status of the route with respect to the Gateway.
- Note that the route's availability is also subject to the Gateway's own
- status conditions and listener status.
-
-
- If the Route's ParentRef specifies an existing Gateway that supports
- Routes of this kind AND that Gateway's controller has sufficient access,
- then that Gateway's controller MUST set the "Accepted" condition on the
- Route, to indicate whether the route has been accepted or rejected by the
- Gateway, and why.
-
-
- A Route MUST be considered "Accepted" if at least one of the Route's
- rules is implemented by the Gateway.
-
-
- There are a number of cases where the "Accepted" condition may not be set
- due to lack of controller visibility, that includes when:
-
-
- * The Route refers to a non-existent parent.
- * The Route is of a type that the controller does not support.
- * The Route is in a namespace the controller does not have access to.
- items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
- properties:
- lastTransitionTime:
- description: |-
- lastTransitionTime is the last time the condition transitioned from one status to another.
- This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
- format: date-time
- type: string
- message:
- description: |-
- message is a human readable message indicating details about the transition.
- This may be an empty string.
- maxLength: 32768
- type: string
- observedGeneration:
- description: |-
- observedGeneration represents the .metadata.generation that the condition was set based upon.
- For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
- with respect to the current state of the instance.
- format: int64
- minimum: 0
- type: integer
- reason:
- description: |-
- reason contains a programmatic identifier indicating the reason for the condition's last transition.
- Producers of specific condition types may define expected values and meanings for this field,
- and whether the values are considered a guaranteed API.
- The value should be a CamelCase string.
- This field may not be empty.
- maxLength: 1024
- minLength: 1
- pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
- type: string
- status:
- description: status of the condition, one of True, False,
- Unknown.
- enum:
- - "True"
- - "False"
- - Unknown
- type: string
- type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
- maxLength: 316
- pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
- type: string
- required:
- - lastTransitionTime
- - message
- - reason
- - status
- - type
- type: object
- maxItems: 8
- minItems: 1
- type: array
- x-kubernetes-list-map-keys:
- - type
- x-kubernetes-list-type: map
- controllerName:
- description: |-
- ControllerName is a domain/path string that indicates the name of the
- controller that wrote this status. This corresponds with the
- controllerName field on GatewayClass.
-
-
- Example: "example.net/gateway-controller".
-
-
- The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
- valid Kubernetes names
- (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
-
- Controllers MUST populate this field when writing status. Controllers should ensure that
- entries to status populated with their ControllerName are cleaned up when they are no
- longer necessary.
- maxLength: 253
- minLength: 1
- pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
- type: string
- parentRef:
- description: |-
- ParentRef corresponds with a ParentRef in the spec that this
- RouteParentStatus struct describes the status of.
- properties:
- group:
- default: gateway.networking.k8s.io
- description: |-
- Group is the group of the referent.
- When unspecified, "gateway.networking.k8s.io" is inferred.
- To set the core API group (such as for a "Service" kind referent),
- Group must be explicitly set to "" (empty string).
-
-
- Support: Core
- maxLength: 253
- pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- kind:
- default: Gateway
- description: |-
- Kind is kind of the referent.
-
-
- There are two kinds of parent resources with "Core" support:
-
-
- * Gateway (Gateway conformance profile)
- * Service (Mesh conformance profile, ClusterIP Services only)
-
-
- Support for other resources is Implementation-Specific.
- maxLength: 63
- minLength: 1
- pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
- type: string
- name:
- description: |-
- Name is the name of the referent.
-
-
- Support: Core
- maxLength: 253
- minLength: 1
- type: string
- namespace:
- description: |-
- Namespace is the namespace of the referent. When unspecified, this refers
- to the local namespace of the Route.
-
-
- Note that there are specific rules for ParentRefs which cross namespace
- boundaries. Cross-namespace references are only valid if they are explicitly
- allowed by something in the namespace they are referring to. For example:
- Gateway has the AllowedRoutes field, and ReferenceGrant provides a
- generic way to enable any other kind of cross-namespace reference.
-
-
-
- ParentRefs from a Route to a Service in the same namespace are "producer"
- routes, which apply default routing rules to inbound connections from
- any namespace to the Service.
-
-
- ParentRefs from a Route to a Service in a different namespace are
- "consumer" routes, and these routing rules are only applied to outbound
- connections originating from the same namespace as the Route, for which
- the intended destination of the connections are a Service targeted as a
- ParentRef of the Route.
-
-
-
- Support: Core
- maxLength: 63
- minLength: 1
- pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
- type: string
- port:
- description: |-
- Port is the network port this Route targets. It can be interpreted
- differently based on the type of parent resource.
-
-
- When the parent resource is a Gateway, this targets all listeners
- listening on the specified port that also support this kind of Route(and
- select this Route). It's not recommended to set `Port` unless the
- networking behaviors specified in a Route must apply to a specific port
- as opposed to a listener(s) whose port(s) may be changed. When both Port
- and SectionName are specified, the name and port of the selected listener
- must match both specified values.
-
-
-
- When the parent resource is a Service, this targets a specific port in the
- Service spec. When both Port (experimental) and SectionName are specified,
- the name and port of the selected port must match both specified values.
-
-
-
- Implementations MAY choose to support other parent resources.
- Implementations supporting other types of parent resources MUST clearly
- document how/if Port is interpreted.
-
-
- For the purpose of status, an attachment is considered successful as
- long as the parent resource accepts it partially. For example, Gateway
- listeners can restrict which Routes can attach to them by Route kind,
- namespace, or hostname. If 1 of 2 Gateway listeners accept attachment
- from the referencing Route, the Route MUST be considered successfully
- attached. If no Gateway listeners accept attachment from this Route,
- the Route MUST be considered detached from the Gateway.
-
-
- Support: Extended
- format: int32
- maximum: 65535
- minimum: 1
- type: integer
- sectionName:
- description: |-
- SectionName is the name of a section within the target resource. In the
- following resources, SectionName is interpreted as the following:
-
-
- * Gateway: Listener name. When both Port (experimental) and SectionName
- are specified, the name and port of the selected listener must match
- both specified values.
- * Service: Port name. When both Port (experimental) and SectionName
- are specified, the name and port of the selected listener must match
- both specified values.
-
-
- Implementations MAY choose to support attaching Routes to other resources.
- If that is the case, they MUST clearly document how SectionName is
- interpreted.
-
-
- When unspecified (empty string), this will reference the entire resource.
- For the purpose of status, an attachment is considered successful if at
- least one section in the parent resource accepts it. For example, Gateway
- listeners can restrict which Routes can attach to them by Route kind,
- namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from
- the referencing Route, the Route MUST be considered successfully
- attached. If no Gateway listeners accept attachment from this Route, the
- Route MUST be considered detached from the Gateway.
-
-
- Support: Core
- maxLength: 253
- minLength: 1
- pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- required:
- - name
- type: object
- required:
- - controllerName
- - parentRef
- type: object
- maxItems: 32
- type: array
- required:
- - parents
- type: object
- type: object
- served: true
- storage: false
status:
acceptedNames:
kind: ""
@@ -8908,8 +6327,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
- gateway.networking.k8s.io/bundle-version: v1.1.0
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+ gateway.networking.k8s.io/bundle-version: v1.2.1
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: httproutes.gateway.networking.k8s.io
@@ -8968,21 +6387,17 @@ spec:
performing a match and (absent of any applicable header modification
configuration) MUST forward this header unmodified to the backend.
-
Valid values for Hostnames are determined by RFC 1123 definition of a
hostname with 2 notable exceptions:
-
1. IPs are not allowed.
2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
label must appear by itself as the first label.
-
If a hostname is specified by both the Listener and HTTPRoute, there
must be at least one intersecting hostname for the HTTPRoute to be
attached to the Listener. For example:
-
* A Listener with `test.example.com` as the hostname matches HTTPRoutes
that have either not specified any hostnames, or have specified at
least one of `test.example.com` or `*.example.com`.
@@ -8993,55 +6408,45 @@ spec:
all match. On the other hand, `example.com` and `test.example.net` would
not match.
-
Hostnames that are prefixed with a wildcard label (`*.`) are interpreted
as a suffix match. That means that a match for `*.example.com` would match
both `test.example.com`, and `foo.test.example.com`, but not `example.com`.
-
If both the Listener and HTTPRoute have specified hostnames, any
HTTPRoute hostnames that do not match the Listener hostname MUST be
ignored. For example, if a Listener specified `*.example.com`, and the
HTTPRoute specified `test.example.com` and `test.example.net`,
`test.example.net` must not be considered for a match.
-
If both the Listener and HTTPRoute have specified hostnames, and none
match with the criteria above, then the HTTPRoute is not accepted. The
implementation must raise an 'Accepted' Condition with a status of
`False` in the corresponding RouteParentStatus.
-
In the event that multiple HTTPRoutes specify intersecting hostnames (e.g.
overlapping wildcard matching and exact matching hostnames), precedence must
be given to rules from the HTTPRoute with the largest number of:
-
* Characters in a matching non-wildcard hostname.
* Characters in a matching hostname.
-
If ties exist across multiple Routes, the matching precedence rules for
HTTPRouteMatches takes over.
-
Support: Core
items:
description: |-
Hostname is the fully qualified domain name of a network host. This matches
the RFC 1123 definition of a hostname with 2 notable exceptions:
-
1. IPs are not allowed.
2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
label must appear by itself as the first label.
-
Hostname can be "precise" which is a domain name without the terminating
dot of a network host (e.g. "foo.example.com") or "wildcard", which is a
domain name prefixed with a single wildcard label (e.g. `*.example.com`).
-
Note that as per RFC1035 and RFC1123, a *label* must consist of lower case
alphanumeric characters or '-', and must start and end with an alphanumeric
character. No other punctuation is allowed.
@@ -9064,21 +6469,16 @@ spec:
create a "producer" route for a Service in a different namespace from the
Route.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
ParentRefs must be _distinct_. This means either that:
-
* They select different objects. If this is the case, then parentRef
entries are distinct. In terms of fields, this means that the
multi-part key defined by `group`, `kind`, `namespace`, and `name` must
@@ -9088,10 +6488,8 @@ spec:
optional fields to different values. If one ParentRef sets a
combination of optional fields, all must set the same combination.
-
Some examples:
-
* If one ParentRef sets `sectionName`, all ParentRefs referencing the
same object must also set `sectionName`.
* If one ParentRef sets `port`, all ParentRefs referencing the same
@@ -9099,14 +6497,12 @@ spec:
* If one ParentRef sets `sectionName` and `port`, all ParentRefs
referencing the same object must also set `sectionName` and `port`.
-
It is possible to separately reference multiple distinct objects that may
be collapsed by an implementation. For example, some implementations may
choose to merge compatible Gateway Listeners together. If that is the
case, the list of routes attached to those resources should also be
merged.
-
Note that for ParentRefs that cross namespace boundaries, there are specific
rules. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example,
@@ -9114,12 +6510,10 @@ spec:
generic way to enable other kinds of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -9130,22 +6524,18 @@ spec:
-
items:
description: |-
ParentReference identifies an API object (usually a Gateway) that can be considered
a parent of this resource (usually a route). There are two kinds of parent resources
with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
properties:
@@ -9157,7 +6547,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -9167,14 +6556,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -9184,7 +6570,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -9194,7 +6579,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -9202,12 +6586,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -9215,7 +6597,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -9226,7 +6607,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -9236,18 +6616,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -9256,7 +6633,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -9267,7 +6643,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -9275,12 +6650,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -9290,7 +6663,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -9330,7 +6702,9 @@ spec:
- path:
type: PathPrefix
value: /
- description: Rules are a list of HTTP matchers, filters and actions.
+ description: |+
+ Rules are a list of HTTP matchers, filters and actions.
+
items:
description: |-
HTTPRouteRule defines semantics for matching an HTTP request based on
@@ -9342,74 +6716,63 @@ spec:
BackendRefs defines the backend(s) where matching requests should be
sent.
-
Failure behavior here depends on how many BackendRefs are specified and
how many are invalid.
-
If *all* entries in BackendRefs are invalid, and there are also no filters
specified in this route rule, *all* traffic which matches this rule MUST
receive a 500 status code.
-
See the HTTPBackendRef definition for the rules about what makes a single
HTTPBackendRef invalid.
-
When a HTTPBackendRef is invalid, 500 status codes MUST be returned for
requests that would have otherwise been routed to an invalid backend. If
multiple backends are specified, and some are invalid, the proportion of
requests that would otherwise have been routed to an invalid backend
MUST receive a 500 status code.
-
For example, if two backends are specified with equal weights, and one is
invalid, 50 percent of traffic must receive a 500. Implementations may
choose how that 50 percent is determined.
+ When a HTTPBackendRef refers to a Service that has no ready endpoints,
+ implementations SHOULD return a 503 for requests to that backend instead.
+ If an implementation chooses to do this, all of the above rules for 500 responses
+ MUST also apply for responses that return a 503.
Support: Core for Kubernetes Service
-
Support: Extended for Kubernetes ServiceImport
-
Support: Implementation-specific for any other resource
-
Support for weight: Core
items:
description: |-
HTTPBackendRef defines how a HTTPRoute forwards a HTTP request.
-
Note that when a namespace different than the local namespace is specified, a
ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
-
When the BackendRef points to a Kubernetes Service, implementations SHOULD
honor the appProtocol field if it is set for the target Service Port.
-
Implementations supporting appProtocol SHOULD recognize the Kubernetes
Standard Application Protocols defined in KEP-3726.
-
If a Service appProtocol isn't specified, an implementation MAY infer the
backend protocol through its own means. Implementations MAY infer the
protocol from the Route type referring to the backend Service.
-
If a Route is not able to send traffic to the backend using the specified
protocol then the backend is considered invalid. Implementations MUST set the
"ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason.
-
properties:
filters:
@@ -9417,7 +6780,6 @@ spec:
Filters defined at this level should be executed if and only if the
request is being forwarded to the backend defined here.
-
Support: Implementation-specific (For broader support of filters, use the
Filters field in HTTPRouteRule.)
items:
@@ -9436,10 +6798,8 @@ spec:
"networking.example.net"). ExtensionRef MUST NOT be used for core and
extended filters.
-
This filter can be used multiple times within the same rule.
-
Support: Implementation-specific
properties:
group:
@@ -9471,7 +6831,6 @@ spec:
RequestHeaderModifier defines a schema for a filter that modifies request
headers.
-
Support: Core
properties:
add:
@@ -9480,18 +6839,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -9505,7 +6861,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -9537,18 +6892,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -9562,18 +6914,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -9587,7 +6936,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -9614,49 +6962,42 @@ spec:
x-kubernetes-list-type: map
type: object
requestMirror:
- description: |-
+ description: |+
RequestMirror defines a schema for a filter that mirrors requests.
Requests are sent to the specified destination, but responses from
that destination are ignored.
-
This filter can be used multiple times within the same rule. Note that
not all implementations will be able to support mirroring to multiple
backends.
-
Support: Extended
+
properties:
backendRef:
description: |-
BackendRef references a resource where mirrored requests are sent.
-
Mirrored requests must be sent only to a single destination endpoint
within this BackendRef, irrespective of how many endpoints are present
within this BackendRef.
-
If the referent cannot be found, this BackendRef is invalid and must be
dropped from the Gateway. The controller must ensure the "ResolvedRefs"
condition on the Route status is set to `status: False` and not configure
this backend in the underlying implementation.
-
If there is a cross-namespace reference to an *existing* object
that is not allowed by a ReferenceGrant, the controller must ensure the
"ResolvedRefs" condition on the Route is set to `status: False`,
with the "RefNotPermitted" reason and not configure this backend in the
underlying implementation.
-
In either error case, the Message of the `ResolvedRefs` Condition
should be used to provide more detail about the problem.
-
Support: Extended for Kubernetes Service
-
Support: Implementation-specific for any other resource
properties:
group:
@@ -9673,20 +7014,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -9702,13 +7039,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -9732,15 +7067,56 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind
== ''Service'') ? has(self.port) : true'
+ fraction:
+ description: |+
+ Fraction represents the fraction of requests that should be
+ mirrored to BackendRef.
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ properties:
+ denominator:
+ default: 100
+ format: int32
+ minimum: 1
+ type: integer
+ numerator:
+ format: int32
+ minimum: 0
+ type: integer
+ required:
+ - numerator
+ type: object
+ x-kubernetes-validations:
+ - message: numerator must be less than or equal
+ to denominator
+ rule: self.numerator <= self.denominator
+ percent:
+ description: |+
+ Percent represents the percentage of requests that should be
+ mirrored to BackendRef. Its minimum value is 0 (indicating 0% of
+ requests) and its maximum value is 100 (indicating 100% of requests).
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ format: int32
+ maximum: 100
+ minimum: 0
+ type: integer
required:
- backendRef
type: object
+ x-kubernetes-validations:
+ - message: Only one of percent or fraction may be
+ specified in HTTPRequestMirrorFilter
+ rule: '!(has(self.percent) && has(self.fraction))'
requestRedirect:
description: |-
RequestRedirect defines a schema for a filter that responds to the
request with an HTTP redirection.
-
Support: Core
properties:
hostname:
@@ -9749,7 +7125,6 @@ spec:
header in the response.
When empty, the hostname in the `Host` header of the request is used.
-
Support: Core
maxLength: 253
minLength: 1
@@ -9761,7 +7136,6 @@ spec:
The modified path is then used to construct the `Location` header. When
empty, the request path is used as-is.
-
Support: Extended
properties:
replaceFullPath:
@@ -9777,32 +7151,17 @@ spec:
to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch
of "/xyz" would be modified to "/xyz/bar".
-
Note that this matches the behavior of the PathPrefix match type. This
matches full path elements. A path element refers to the list of labels
in the path split by the `/` separator. When specified, a trailing `/` is
ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all
match the prefix `/abc`, but the path `/abcd` would not.
-
ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.
Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in
the implementation setting the Accepted Condition for the Route to `status: False`.
-
Request Path | Prefix Match | Replace Prefix | Modified Path
- -------------|--------------|----------------|----------
- /foo/bar | /foo | /xyz | /xyz/bar
- /foo/bar | /foo | /xyz/ | /xyz/bar
- /foo/bar | /foo/ | /xyz | /xyz/bar
- /foo/bar | /foo/ | /xyz/ | /xyz/bar
- /foo | /foo | /xyz | /xyz
- /foo/ | /foo | /xyz | /xyz/
- /foo/bar | /foo | | /bar
- /foo/ | /foo | | /
- /foo | /foo | | /
- /foo/ | /foo | / | /
- /foo | /foo | / | /
maxLength: 1024
type: string
type:
@@ -9810,11 +7169,9 @@ spec:
Type defines the type of path modifier. Additional types may be
added in a future release of the API.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -9847,11 +7204,9 @@ spec:
Port is the port to be used in the value of the `Location`
header in the response.
-
If no port is specified, the redirect port MUST be derived using the
following rules:
-
* If redirect scheme is not-empty, the redirect port MUST be the well-known
port associated with the redirect scheme. Specifically "http" to port 80
and "https" to port 443. If the redirect scheme does not have a
@@ -9859,17 +7214,14 @@ spec:
* If redirect scheme is empty, the redirect port MUST be the Gateway
Listener port.
-
Implementations SHOULD NOT add the port number in the 'Location'
header in the following cases:
-
* A Location header that will use HTTP (whether that is determined via
the Listener protocol or the Scheme field) _and_ use port 80.
* A Location header that will use HTTPS (whether that is determined via
the Listener protocol or the Scheme field) _and_ use port 443.
-
Support: Extended
format: int32
maximum: 65535
@@ -9880,20 +7232,16 @@ spec:
Scheme is the scheme to be used in the value of the `Location` header in
the response. When empty, the scheme of the request is used.
-
Scheme redirects can affect the port of the redirect, for more information,
refer to the documentation for the port field of this filter.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
-
Support: Extended
enum:
- http
@@ -9904,16 +7252,13 @@ spec:
description: |-
StatusCode is the HTTP status code to be used in response.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
-
Support: Core
enum:
- 301
@@ -9925,7 +7270,6 @@ spec:
ResponseHeaderModifier defines a schema for a filter that modifies response
headers.
-
Support: Extended
properties:
add:
@@ -9934,18 +7278,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -9959,7 +7300,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -9991,18 +7331,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -10016,18 +7353,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -10041,7 +7375,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -10072,17 +7405,14 @@ spec:
Type identifies the type of filter to apply. As with other API fields,
types are classified into three conformance levels:
-
- Core: Filter types and their corresponding configuration defined by
"Support: Core" in this package, e.g. "RequestHeaderModifier". All
implementations must support core filters.
-
- Extended: Filter types and their corresponding configuration defined by
"Support: Extended" in this package, e.g. "RequestMirror". Implementers
are encouraged to support extended filters.
-
- Implementation-specific: Filters that are defined and supported by
specific vendors.
In the future, filters showing convergence in behavior across multiple
@@ -10091,20 +7421,16 @@ spec:
is specified using the ExtensionRef field. `Type` should be set to
"ExtensionRef" for custom filters.
-
Implementers are encouraged to define custom implementation types to
extend the core API with implementation-specific behavior.
-
If a reference to a custom filter type cannot be resolved, the filter
MUST NOT be skipped. Instead, requests that would have been processed by
that filter MUST receive a HTTP error response.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -10120,7 +7446,6 @@ spec:
description: |-
URLRewrite defines a schema for a filter that modifies a request during forwarding.
-
Support: Extended
properties:
hostname:
@@ -10128,7 +7453,6 @@ spec:
Hostname is the value to be used to replace the Host header value during
forwarding.
-
Support: Extended
maxLength: 253
minLength: 1
@@ -10138,7 +7462,6 @@ spec:
description: |-
Path defines a path rewrite.
-
Support: Extended
properties:
replaceFullPath:
@@ -10154,32 +7477,17 @@ spec:
to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch
of "/xyz" would be modified to "/xyz/bar".
-
Note that this matches the behavior of the PathPrefix match type. This
matches full path elements. A path element refers to the list of labels
in the path split by the `/` separator. When specified, a trailing `/` is
ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all
match the prefix `/abc`, but the path `/abcd` would not.
-
ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.
Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in
the implementation setting the Accepted Condition for the Route to `status: False`.
-
Request Path | Prefix Match | Replace Prefix | Modified Path
- -------------|--------------|----------------|----------
- /foo/bar | /foo | /xyz | /xyz/bar
- /foo/bar | /foo | /xyz/ | /xyz/bar
- /foo/bar | /foo/ | /xyz | /xyz/bar
- /foo/bar | /foo/ | /xyz/ | /xyz/bar
- /foo | /foo | /xyz | /xyz
- /foo/ | /foo | /xyz | /xyz/
- /foo/bar | /foo | | /bar
- /foo/ | /foo | | /
- /foo | /foo | | /
- /foo/ | /foo | / | /
- /foo | /foo | / | /
maxLength: 1024
type: string
type:
@@ -10187,11 +7495,9 @@ spec:
Type defines the type of path modifier. Additional types may be
added in a future release of the API.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -10304,20 +7610,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -10333,13 +7635,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -10366,13 +7666,11 @@ spec:
implementation supports. Weight is not a percentage and the sum of
weights does not need to equal 100.
-
If only one backend is specified and it has a weight greater than 0, 100%
of the traffic is forwarded to that backend. If weight is set to 0, no
traffic should be forwarded for this entry. If unspecified, weight
defaults to 1.
-
Support for this field varies based on the context where used.
format: int32
maximum: 1000000
@@ -10392,37 +7690,30 @@ spec:
Filters define the filters that are applied to requests that match
this rule.
-
Wherever possible, implementations SHOULD implement filters in the order
they are specified.
-
Implementations MAY choose to implement this ordering strictly, rejecting
any combination or order of filters that can not be supported. If implementations
choose a strict interpretation of filter ordering, they MUST clearly document
that behavior.
-
To reject an invalid combination or order of filters, implementations SHOULD
consider the Route Rules with this configuration invalid. If all Route Rules
in a Route are invalid, the entire Route would be considered invalid. If only
a portion of Route Rules are invalid, implementations MUST set the
"PartiallyInvalid" condition for the Route.
-
Conformance-levels at this level are defined based on the type of filter:
-
- ALL core filters MUST be supported by all implementations.
- Implementers are encouraged to support extended filters.
- Implementation-specific custom filters have no API guarantees across
implementations.
-
Specifying the same filter multiple times is not supported unless explicitly
indicated in the filter.
-
All filters are expected to be compatible with each other except for the
URLRewrite and RequestRedirect filters, which may not be combined. If an
implementation can not support other combinations of filters, they must clearly
@@ -10431,7 +7722,6 @@ spec:
`False`, implementations may use the `IncompatibleFilters` reason to specify
this configuration error.
-
Support: Core
items:
description: |-
@@ -10449,10 +7739,8 @@ spec:
"networking.example.net"). ExtensionRef MUST NOT be used for core and
extended filters.
-
This filter can be used multiple times within the same rule.
-
Support: Implementation-specific
properties:
group:
@@ -10484,7 +7772,6 @@ spec:
RequestHeaderModifier defines a schema for a filter that modifies request
headers.
-
Support: Core
properties:
add:
@@ -10493,18 +7780,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -10517,7 +7801,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -10549,18 +7832,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -10574,18 +7854,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -10598,7 +7875,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -10625,49 +7901,42 @@ spec:
x-kubernetes-list-type: map
type: object
requestMirror:
- description: |-
+ description: |+
RequestMirror defines a schema for a filter that mirrors requests.
Requests are sent to the specified destination, but responses from
that destination are ignored.
-
This filter can be used multiple times within the same rule. Note that
not all implementations will be able to support mirroring to multiple
backends.
-
Support: Extended
+
properties:
backendRef:
description: |-
BackendRef references a resource where mirrored requests are sent.
-
Mirrored requests must be sent only to a single destination endpoint
within this BackendRef, irrespective of how many endpoints are present
within this BackendRef.
-
If the referent cannot be found, this BackendRef is invalid and must be
dropped from the Gateway. The controller must ensure the "ResolvedRefs"
condition on the Route status is set to `status: False` and not configure
this backend in the underlying implementation.
-
If there is a cross-namespace reference to an *existing* object
that is not allowed by a ReferenceGrant, the controller must ensure the
"ResolvedRefs" condition on the Route is set to `status: False`,
with the "RefNotPermitted" reason and not configure this backend in the
underlying implementation.
-
In either error case, the Message of the `ResolvedRefs` Condition
should be used to provide more detail about the problem.
-
Support: Extended for Kubernetes Service
-
Support: Implementation-specific for any other resource
properties:
group:
@@ -10684,20 +7953,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -10713,13 +7978,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -10743,15 +8006,56 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
+ fraction:
+ description: |+
+ Fraction represents the fraction of requests that should be
+ mirrored to BackendRef.
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ properties:
+ denominator:
+ default: 100
+ format: int32
+ minimum: 1
+ type: integer
+ numerator:
+ format: int32
+ minimum: 0
+ type: integer
+ required:
+ - numerator
+ type: object
+ x-kubernetes-validations:
+ - message: numerator must be less than or equal to
+ denominator
+ rule: self.numerator <= self.denominator
+ percent:
+ description: |+
+ Percent represents the percentage of requests that should be
+ mirrored to BackendRef. Its minimum value is 0 (indicating 0% of
+ requests) and its maximum value is 100 (indicating 100% of requests).
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ format: int32
+ maximum: 100
+ minimum: 0
+ type: integer
required:
- backendRef
type: object
+ x-kubernetes-validations:
+ - message: Only one of percent or fraction may be specified
+ in HTTPRequestMirrorFilter
+ rule: '!(has(self.percent) && has(self.fraction))'
requestRedirect:
description: |-
RequestRedirect defines a schema for a filter that responds to the
request with an HTTP redirection.
-
Support: Core
properties:
hostname:
@@ -10760,7 +8064,6 @@ spec:
header in the response.
When empty, the hostname in the `Host` header of the request is used.
-
Support: Core
maxLength: 253
minLength: 1
@@ -10772,7 +8075,6 @@ spec:
The modified path is then used to construct the `Location` header. When
empty, the request path is used as-is.
-
Support: Extended
properties:
replaceFullPath:
@@ -10788,32 +8090,17 @@ spec:
to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch
of "/xyz" would be modified to "/xyz/bar".
-
Note that this matches the behavior of the PathPrefix match type. This
matches full path elements. A path element refers to the list of labels
in the path split by the `/` separator. When specified, a trailing `/` is
ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all
match the prefix `/abc`, but the path `/abcd` would not.
-
ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.
Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in
the implementation setting the Accepted Condition for the Route to `status: False`.
-
Request Path | Prefix Match | Replace Prefix | Modified Path
- -------------|--------------|----------------|----------
- /foo/bar | /foo | /xyz | /xyz/bar
- /foo/bar | /foo | /xyz/ | /xyz/bar
- /foo/bar | /foo/ | /xyz | /xyz/bar
- /foo/bar | /foo/ | /xyz/ | /xyz/bar
- /foo | /foo | /xyz | /xyz
- /foo/ | /foo | /xyz | /xyz/
- /foo/bar | /foo | | /bar
- /foo/ | /foo | | /
- /foo | /foo | | /
- /foo/ | /foo | / | /
- /foo | /foo | / | /
maxLength: 1024
type: string
type:
@@ -10821,11 +8108,9 @@ spec:
Type defines the type of path modifier. Additional types may be
added in a future release of the API.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -10858,11 +8143,9 @@ spec:
Port is the port to be used in the value of the `Location`
header in the response.
-
If no port is specified, the redirect port MUST be derived using the
following rules:
-
* If redirect scheme is not-empty, the redirect port MUST be the well-known
port associated with the redirect scheme. Specifically "http" to port 80
and "https" to port 443. If the redirect scheme does not have a
@@ -10870,17 +8153,14 @@ spec:
* If redirect scheme is empty, the redirect port MUST be the Gateway
Listener port.
-
Implementations SHOULD NOT add the port number in the 'Location'
header in the following cases:
-
* A Location header that will use HTTP (whether that is determined via
the Listener protocol or the Scheme field) _and_ use port 80.
* A Location header that will use HTTPS (whether that is determined via
the Listener protocol or the Scheme field) _and_ use port 443.
-
Support: Extended
format: int32
maximum: 65535
@@ -10891,20 +8171,16 @@ spec:
Scheme is the scheme to be used in the value of the `Location` header in
the response. When empty, the scheme of the request is used.
-
Scheme redirects can affect the port of the redirect, for more information,
refer to the documentation for the port field of this filter.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
-
Support: Extended
enum:
- http
@@ -10915,16 +8191,13 @@ spec:
description: |-
StatusCode is the HTTP status code to be used in response.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
-
Support: Core
enum:
- 301
@@ -10936,7 +8209,6 @@ spec:
ResponseHeaderModifier defines a schema for a filter that modifies response
headers.
-
Support: Extended
properties:
add:
@@ -10945,18 +8217,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -10969,7 +8238,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -11001,18 +8269,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -11026,18 +8291,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -11050,7 +8312,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -11081,17 +8342,14 @@ spec:
Type identifies the type of filter to apply. As with other API fields,
types are classified into three conformance levels:
-
- Core: Filter types and their corresponding configuration defined by
"Support: Core" in this package, e.g. "RequestHeaderModifier". All
implementations must support core filters.
-
- Extended: Filter types and their corresponding configuration defined by
"Support: Extended" in this package, e.g. "RequestMirror". Implementers
are encouraged to support extended filters.
-
- Implementation-specific: Filters that are defined and supported by
specific vendors.
In the future, filters showing convergence in behavior across multiple
@@ -11100,20 +8358,16 @@ spec:
is specified using the ExtensionRef field. `Type` should be set to
"ExtensionRef" for custom filters.
-
Implementers are encouraged to define custom implementation types to
extend the core API with implementation-specific behavior.
-
If a reference to a custom filter type cannot be resolved, the filter
MUST NOT be skipped. Instead, requests that would have been processed by
that filter MUST receive a HTTP error response.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -11129,7 +8383,6 @@ spec:
description: |-
URLRewrite defines a schema for a filter that modifies a request during forwarding.
-
Support: Extended
properties:
hostname:
@@ -11137,7 +8390,6 @@ spec:
Hostname is the value to be used to replace the Host header value during
forwarding.
-
Support: Extended
maxLength: 253
minLength: 1
@@ -11147,7 +8399,6 @@ spec:
description: |-
Path defines a path rewrite.
-
Support: Extended
properties:
replaceFullPath:
@@ -11163,32 +8414,17 @@ spec:
to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch
of "/xyz" would be modified to "/xyz/bar".
-
Note that this matches the behavior of the PathPrefix match type. This
matches full path elements. A path element refers to the list of labels
in the path split by the `/` separator. When specified, a trailing `/` is
ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all
match the prefix `/abc`, but the path `/abcd` would not.
-
ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.
Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in
the implementation setting the Accepted Condition for the Route to `status: False`.
-
Request Path | Prefix Match | Replace Prefix | Modified Path
- -------------|--------------|----------------|----------
- /foo/bar | /foo | /xyz | /xyz/bar
- /foo/bar | /foo | /xyz/ | /xyz/bar
- /foo/bar | /foo/ | /xyz | /xyz/bar
- /foo/bar | /foo/ | /xyz/ | /xyz/bar
- /foo | /foo | /xyz | /xyz
- /foo/ | /foo | /xyz | /xyz/
- /foo/bar | /foo | | /bar
- /foo/ | /foo | | /
- /foo | /foo | | /
- /foo/ | /foo | / | /
- /foo | /foo | / | /
maxLength: 1024
type: string
type:
@@ -11196,11 +8432,9 @@ spec:
Type defines the type of path modifier. Additional types may be
added in a future release of the API.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -11301,10 +8535,8 @@ spec:
HTTP requests. Each match is independent, i.e. this rule will be matched
if **any** one of the matches is satisfied.
-
For example, take the following matches configuration:
-
```
matches:
- path:
@@ -11316,65 +8548,54 @@ spec:
value: "/v2/foo"
```
-
For a request to match against this rule, a request must satisfy
EITHER of the two conditions:
-
- path prefixed with `/foo` AND contains the header `version: v2`
- path prefix of `/v2/foo`
-
See the documentation for HTTPRouteMatch on how to specify multiple
match conditions that should be ANDed together.
-
If no matches are specified, the default is a prefix
path match on "/", which has the effect of matching every
HTTP request.
-
Proxy or Load Balancer routing configuration generated from HTTPRoutes
MUST prioritize matches based on the following criteria, continuing on
ties. Across all rules specified on applicable Routes, precedence must be
given to the match having:
-
* "Exact" path match.
* "Prefix" path match with largest number of characters.
* Method match.
* Largest number of header matches.
* Largest number of query param matches.
-
Note: The precedence of RegularExpression path matches are implementation-specific.
-
If ties still exist across multiple Routes, matching precedence MUST be
determined in order of the following criteria, continuing on ties:
-
* The oldest Route based on creation timestamp.
* The Route appearing first in alphabetical order by
"{namespace}/{name}".
-
If ties still exist within an HTTPRoute, matching precedence MUST be granted
to the FIRST matching rule (in list order) with a match meeting the above
criteria.
-
When no rules matching a request have been successfully attached to the
parent a request is coming from, a HTTP 404 status code MUST be returned.
items:
description: "HTTPRouteMatch defines the predicate used to
match requests to a given\naction. Multiple match types
are ANDed together, i.e. the match will\nevaluate to true
- only if all conditions are satisfied.\n\n\nFor example,
- the match below will match a HTTP request only if its path\nstarts
- with `/foo` AND it contains the `version: v1` header:\n\n\n```\nmatch:\n\n\n\tpath:\n\t
+ only if all conditions are satisfied.\n\nFor example, the
+ match below will match a HTTP request only if its path\nstarts
+ with `/foo` AND it contains the `version: v1` header:\n\n```\nmatch:\n\n\tpath:\n\t
\ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t
- \ value \"v1\"\n\n\n```"
+ \ value \"v1\"\n\n```"
properties:
headers:
description: |-
@@ -11391,14 +8612,12 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, only the first
entry with an equivalent name MUST be considered for a match. Subsequent
entries with an equivalent header name MUST be ignored. Due to the
case-insensitivity of header names, "foo" and "Foo" are considered
equivalent.
-
When a header is repeated in an HTTP request, it is
implementation-specific behavior as to how this is represented.
Generally, proxies should follow the guidance from the RFC:
@@ -11413,13 +8632,10 @@ spec:
description: |-
Type specifies how to match against the value of the header.
-
Support: Core (Exact)
-
Support: Implementation-specific (RegularExpression)
-
Since RegularExpression HeaderMatchType has implementation-specific
conformance, implementations can support POSIX, PCRE or any other dialects
of regular expressions. Please read the implementation's documentation to
@@ -11449,7 +8665,6 @@ spec:
When specified, this route will be matched only if the request has the
specified method.
-
Support: Extended
enum:
- GET
@@ -11475,10 +8690,8 @@ spec:
description: |-
Type specifies how to match against the path Value.
-
Support: Core (Exact, PathPrefix)
-
Support: Implementation-specific (RegularExpression)
enum:
- Exact
@@ -11543,7 +8756,6 @@ spec:
values are ANDed together, meaning, a request must match all the
specified query parameters to select the route.
-
Support: Extended
items:
description: |-
@@ -11556,12 +8768,10 @@ spec:
exact string match. (See
https://tools.ietf.org/html/rfc7230#section-2.7.3).
-
If multiple entries specify equivalent query param names, only the first
entry with an equivalent name MUST be considered for a match. Subsequent
entries with an equivalent query param name MUST be ignored.
-
If a query param is repeated in an HTTP request, the behavior is
purposely left undefined, since different data planes have different
capabilities. However, it is *recommended* that implementations should
@@ -11569,7 +8779,6 @@ spec:
as this behavior is expected in other load balancing contexts outside of
the Gateway API.
-
Users SHOULD NOT route traffic based on repeated query params to guard
themselves against potential differences in the implementations.
maxLength: 256
@@ -11581,13 +8790,10 @@ spec:
description: |-
Type specifies how to match against the value of the query parameter.
-
Support: Extended (Exact)
-
Support: Implementation-specific (RegularExpression)
-
Since RegularExpression QueryParamMatchType has Implementation-specific
conformance, implementations can support POSIX, PCRE or any other
dialects of regular expressions. Please read the implementation's
@@ -11612,17 +8818,114 @@ spec:
- name
x-kubernetes-list-type: map
type: object
- maxItems: 8
+ maxItems: 64
type: array
+ name:
+ description: |
+ Name is the name of the route rule. This name MUST be unique within a Route if it is set.
+
+ Support: Extended
+ maxLength: 253
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ retry:
+ description: |+
+ Retry defines the configuration for when to retry an HTTP request.
+
+ Support: Extended
+
+ properties:
+ attempts:
+ description: |-
+ Attempts specifies the maxmimum number of times an individual request
+ from the gateway to a backend should be retried.
+
+ If the maximum number of retries has been attempted without a successful
+ response from the backend, the Gateway MUST return an error.
+
+ When this field is unspecified, the number of times to attempt to retry
+ a backend request is implementation-specific.
+
+ Support: Extended
+ type: integer
+ backoff:
+ description: |-
+ Backoff specifies the minimum duration a Gateway should wait between
+ retry attempts and is represented in Gateway API Duration formatting.
+
+ For example, setting the `rules[].retry.backoff` field to the value
+ `100ms` will cause a backend request to first be retried approximately
+ 100 milliseconds after timing out or receiving a response code configured
+ to be retryable.
+
+ An implementation MAY use an exponential or alternative backoff strategy
+ for subsequent retry attempts, MAY cap the maximum backoff duration to
+ some amount greater than the specified minimum, and MAY add arbitrary
+ jitter to stagger requests, as long as unsuccessful backend requests are
+ not retried before the configured minimum duration.
+
+ If a Request timeout (`rules[].timeouts.request`) is configured on the
+ route, the entire duration of the initial request and any retry attempts
+ MUST not exceed the Request timeout duration. If any retry attempts are
+ still in progress when the Request timeout duration has been reached,
+ these SHOULD be canceled if possible and the Gateway MUST immediately
+ return a timeout error.
+
+ If a BackendRequest timeout (`rules[].timeouts.backendRequest`) is
+ configured on the route, any retry attempts which reach the configured
+ BackendRequest timeout duration without a response SHOULD be canceled if
+ possible and the Gateway should wait for at least the specified backoff
+ duration before attempting to retry the backend request again.
+
+ If a BackendRequest timeout is _not_ configured on the route, retry
+ attempts MAY time out after an implementation default duration, or MAY
+ remain pending until a configured Request timeout or implementation
+ default duration for total request time is reached.
+
+ When this field is unspecified, the time to wait between retry attempts
+ is implementation-specific.
+
+ Support: Extended
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ codes:
+ description: |-
+ Codes defines the HTTP response status codes for which a backend request
+ should be retried.
+
+ Support: Extended
+ items:
+ description: |-
+ HTTPRouteRetryStatusCode defines an HTTP response status code for
+ which a backend request should be retried.
+
+ Implementations MUST support the following status codes as retryable:
+
+ * 500
+ * 502
+ * 503
+ * 504
+
+ Implementations MAY support specifying additional discrete values in the
+ 500-599 range.
+
+ Implementations MAY support specifying discrete values in the 400-499 range,
+ which are often inadvisable to retry.
+
+
+ maximum: 599
+ minimum: 400
+ type: integer
+ type: array
+ type: object
sessionPersistence:
description: |+
SessionPersistence defines and configures session persistence
for the route rule.
-
Support: Extended
-
properties:
absoluteTimeout:
description: |-
@@ -11630,7 +8933,6 @@ spec:
session. Once the AbsoluteTimeout duration has elapsed, the
session becomes invalid.
-
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
@@ -11639,7 +8941,6 @@ spec:
CookieConfig provides configuration settings that are specific
to cookie-based session persistence.
-
Support: Core
properties:
lifetimeType:
@@ -11651,20 +8952,16 @@ spec:
attributes, while a session cookie is deleted when the current
session ends.
-
When set to "Permanent", AbsoluteTimeout indicates the
cookie's lifetime via the Expires or Max-Age cookie attributes
and is required.
-
When set to "Session", AbsoluteTimeout indicates the
absolute lifetime of the cookie tracked by the gateway and
is optional.
-
Support: Core for "Session" type
-
Support: Extended for "Permanent" type
enum:
- Permanent
@@ -11677,7 +8974,6 @@ spec:
Once the session has been idle for more than the specified
IdleTimeout duration, the session becomes invalid.
-
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
@@ -11688,7 +8984,6 @@ spec:
should avoid reusing session names to prevent unintended
consequences, such as rejection or unpredictable behavior.
-
Support: Implementation-specific
maxLength: 128
type: string
@@ -11699,10 +8994,8 @@ spec:
the use a header or cookie. Defaults to cookie based session
persistence.
-
Support: Core for "Cookie" type
-
Support: Extended for "Header" type
enum:
- Cookie
@@ -11712,16 +9005,13 @@ spec:
x-kubernetes-validations:
- message: AbsoluteTimeout must be specified when cookie lifetimeType
is Permanent
- rule: '!has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType
- != ''Permanent'' || has(self.absoluteTimeout)'
+ rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType)
+ || self.cookieConfig.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)'
timeouts:
- description: |+
+ description: |-
Timeouts defines the timeouts that can be configured for an HTTP request.
-
Support: Extended
-
-
properties:
backendRequest:
description: |-
@@ -11729,21 +9019,19 @@ spec:
to a backend. This covers the time from when the request first starts being
sent from the gateway to when the full response has been received from the backend.
-
Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout
completely. Implementations that cannot completely disable the timeout MUST
instead interpret the zero duration as the longest possible value to which
the timeout can be set.
-
An entire client HTTP transaction with a gateway, covered by the Request timeout,
may result in more than one call from the gateway to the destination backend,
for example, if automatic retries are supported.
-
- Because the Request timeout encompasses the BackendRequest timeout, the value of
- BackendRequest must be <= the value of Request timeout.
-
+ The value of BackendRequest must be a Gateway API Duration string as defined by
+ GEP-2257. When this field is unspecified, its behavior is implementation-specific;
+ when specified, the value of BackendRequest must be no more than the value of the
+ Request timeout (since the Request timeout encompasses the BackendRequest timeout).
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
@@ -11754,26 +9042,22 @@ spec:
If the gateway has not been able to respond before this deadline is met, the gateway
MUST return a timeout error.
-
For example, setting the `rules.timeouts.request` field to the value `10s` in an
`HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds
to complete.
-
Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout
completely. Implementations that cannot completely disable the timeout MUST
instead interpret the zero duration as the longest possible value to which
the timeout can be set.
-
This timeout is intended to cover as close to the whole request-response transaction
as possible although an implementation MAY choose to start the timeout after the entire
request stream has been received instead of immediately after the transaction is
initiated by the client.
-
- When this field is unspecified, request timeout behavior is implementation-specific.
-
+ The value of Request is a Gateway API Duration string as defined by GEP-2257. When this
+ field is unspecified, request timeout behavior is implementation-specific.
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
@@ -11828,6 +9112,24 @@ spec:
!= ''PathPrefix'') ? false : true) : true'
maxItems: 16
type: array
+ x-kubernetes-validations:
+ - message: While 16 rules and 64 matches per rule are allowed, the
+ total number of matches across all rules in a route must be less
+ than 128
+ rule: '(self.size() > 0 ? self[0].matches.size() : 0) + (self.size()
+ > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size()
+ : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size()
+ > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size()
+ : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size()
+ > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size()
+ : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size()
+ > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size()
+ : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size()
+ > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size()
+ : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128'
+ - message: Rule name must be unique within the route
+ rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)
+ && l1.name == l2.name))
type: object
status:
description: Status defines the current state of HTTPRoute.
@@ -11841,13 +9143,11 @@ spec:
first sees the route and should update the entry as appropriate when the
route or gateway is modified.
-
Note that parent references that cannot be resolved by an implementation
of this API will not be added to this list. Implementations of this API
can only populate Route status for the Gateways/parent resources they are
responsible for.
-
A maximum of 32 Gateways will be represented in this list. An empty list
means the route has not been attached to any Gateway.
items:
@@ -11861,38 +9161,24 @@ spec:
Note that the route's availability is also subject to the Gateway's own
status conditions and listener status.
-
If the Route's ParentRef specifies an existing Gateway that supports
Routes of this kind AND that Gateway's controller has sufficient access,
then that Gateway's controller MUST set the "Accepted" condition on the
Route, to indicate whether the route has been accepted or rejected by the
Gateway, and why.
-
A Route MUST be considered "Accepted" if at least one of the Route's
rules is implemented by the Gateway.
-
There are a number of cases where the "Accepted" condition may not be set
due to lack of controller visibility, that includes when:
-
* The Route refers to a non-existent parent.
* The Route is of a type that the controller does not support.
* The Route is in a namespace the controller does not have access to.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -11934,12 +9220,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -11962,15 +9243,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
@@ -11991,7 +9269,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -12001,14 +9278,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -12018,7 +9292,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -12028,7 +9301,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -12036,12 +9308,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -12049,7 +9319,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -12060,7 +9329,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -12070,18 +9338,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -12090,7 +9355,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -12101,7 +9365,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -12109,12 +9372,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -12124,7 +9385,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -12193,21 +9453,17 @@ spec:
performing a match and (absent of any applicable header modification
configuration) MUST forward this header unmodified to the backend.
-
Valid values for Hostnames are determined by RFC 1123 definition of a
hostname with 2 notable exceptions:
-
1. IPs are not allowed.
2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
label must appear by itself as the first label.
-
If a hostname is specified by both the Listener and HTTPRoute, there
must be at least one intersecting hostname for the HTTPRoute to be
attached to the Listener. For example:
-
* A Listener with `test.example.com` as the hostname matches HTTPRoutes
that have either not specified any hostnames, or have specified at
least one of `test.example.com` or `*.example.com`.
@@ -12218,55 +9474,45 @@ spec:
all match. On the other hand, `example.com` and `test.example.net` would
not match.
-
Hostnames that are prefixed with a wildcard label (`*.`) are interpreted
as a suffix match. That means that a match for `*.example.com` would match
both `test.example.com`, and `foo.test.example.com`, but not `example.com`.
-
If both the Listener and HTTPRoute have specified hostnames, any
HTTPRoute hostnames that do not match the Listener hostname MUST be
ignored. For example, if a Listener specified `*.example.com`, and the
HTTPRoute specified `test.example.com` and `test.example.net`,
`test.example.net` must not be considered for a match.
-
If both the Listener and HTTPRoute have specified hostnames, and none
match with the criteria above, then the HTTPRoute is not accepted. The
implementation must raise an 'Accepted' Condition with a status of
`False` in the corresponding RouteParentStatus.
-
In the event that multiple HTTPRoutes specify intersecting hostnames (e.g.
overlapping wildcard matching and exact matching hostnames), precedence must
be given to rules from the HTTPRoute with the largest number of:
-
* Characters in a matching non-wildcard hostname.
* Characters in a matching hostname.
-
If ties exist across multiple Routes, the matching precedence rules for
HTTPRouteMatches takes over.
-
Support: Core
items:
description: |-
Hostname is the fully qualified domain name of a network host. This matches
the RFC 1123 definition of a hostname with 2 notable exceptions:
-
1. IPs are not allowed.
2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
label must appear by itself as the first label.
-
Hostname can be "precise" which is a domain name without the terminating
dot of a network host (e.g. "foo.example.com") or "wildcard", which is a
domain name prefixed with a single wildcard label (e.g. `*.example.com`).
-
Note that as per RFC1035 and RFC1123, a *label* must consist of lower case
alphanumeric characters or '-', and must start and end with an alphanumeric
character. No other punctuation is allowed.
@@ -12289,21 +9535,16 @@ spec:
create a "producer" route for a Service in a different namespace from the
Route.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
ParentRefs must be _distinct_. This means either that:
-
* They select different objects. If this is the case, then parentRef
entries are distinct. In terms of fields, this means that the
multi-part key defined by `group`, `kind`, `namespace`, and `name` must
@@ -12313,10 +9554,8 @@ spec:
optional fields to different values. If one ParentRef sets a
combination of optional fields, all must set the same combination.
-
Some examples:
-
* If one ParentRef sets `sectionName`, all ParentRefs referencing the
same object must also set `sectionName`.
* If one ParentRef sets `port`, all ParentRefs referencing the same
@@ -12324,14 +9563,12 @@ spec:
* If one ParentRef sets `sectionName` and `port`, all ParentRefs
referencing the same object must also set `sectionName` and `port`.
-
It is possible to separately reference multiple distinct objects that may
be collapsed by an implementation. For example, some implementations may
choose to merge compatible Gateway Listeners together. If that is the
case, the list of routes attached to those resources should also be
merged.
-
Note that for ParentRefs that cross namespace boundaries, there are specific
rules. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example,
@@ -12339,12 +9576,10 @@ spec:
generic way to enable other kinds of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -12355,22 +9590,18 @@ spec:
-
items:
description: |-
ParentReference identifies an API object (usually a Gateway) that can be considered
a parent of this resource (usually a route). There are two kinds of parent resources
with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
properties:
@@ -12382,7 +9613,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -12392,14 +9622,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -12409,7 +9636,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -12419,7 +9645,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -12427,12 +9652,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -12440,7 +9663,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -12451,7 +9673,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -12461,18 +9682,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -12481,7 +9699,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -12492,7 +9709,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -12500,12 +9716,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -12515,7 +9729,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -12555,7 +9768,9 @@ spec:
- path:
type: PathPrefix
value: /
- description: Rules are a list of HTTP matchers, filters and actions.
+ description: |+
+ Rules are a list of HTTP matchers, filters and actions.
+
items:
description: |-
HTTPRouteRule defines semantics for matching an HTTP request based on
@@ -12567,74 +9782,63 @@ spec:
BackendRefs defines the backend(s) where matching requests should be
sent.
-
Failure behavior here depends on how many BackendRefs are specified and
how many are invalid.
-
If *all* entries in BackendRefs are invalid, and there are also no filters
specified in this route rule, *all* traffic which matches this rule MUST
receive a 500 status code.
-
See the HTTPBackendRef definition for the rules about what makes a single
HTTPBackendRef invalid.
-
When a HTTPBackendRef is invalid, 500 status codes MUST be returned for
requests that would have otherwise been routed to an invalid backend. If
multiple backends are specified, and some are invalid, the proportion of
requests that would otherwise have been routed to an invalid backend
MUST receive a 500 status code.
-
For example, if two backends are specified with equal weights, and one is
invalid, 50 percent of traffic must receive a 500. Implementations may
choose how that 50 percent is determined.
+ When a HTTPBackendRef refers to a Service that has no ready endpoints,
+ implementations SHOULD return a 503 for requests to that backend instead.
+ If an implementation chooses to do this, all of the above rules for 500 responses
+ MUST also apply for responses that return a 503.
Support: Core for Kubernetes Service
-
Support: Extended for Kubernetes ServiceImport
-
Support: Implementation-specific for any other resource
-
Support for weight: Core
items:
description: |-
HTTPBackendRef defines how a HTTPRoute forwards a HTTP request.
-
Note that when a namespace different than the local namespace is specified, a
ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
-
When the BackendRef points to a Kubernetes Service, implementations SHOULD
honor the appProtocol field if it is set for the target Service Port.
-
Implementations supporting appProtocol SHOULD recognize the Kubernetes
Standard Application Protocols defined in KEP-3726.
-
If a Service appProtocol isn't specified, an implementation MAY infer the
backend protocol through its own means. Implementations MAY infer the
protocol from the Route type referring to the backend Service.
-
If a Route is not able to send traffic to the backend using the specified
protocol then the backend is considered invalid. Implementations MUST set the
"ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason.
-
properties:
filters:
@@ -12642,7 +9846,6 @@ spec:
Filters defined at this level should be executed if and only if the
request is being forwarded to the backend defined here.
-
Support: Implementation-specific (For broader support of filters, use the
Filters field in HTTPRouteRule.)
items:
@@ -12661,10 +9864,8 @@ spec:
"networking.example.net"). ExtensionRef MUST NOT be used for core and
extended filters.
-
This filter can be used multiple times within the same rule.
-
Support: Implementation-specific
properties:
group:
@@ -12696,7 +9897,6 @@ spec:
RequestHeaderModifier defines a schema for a filter that modifies request
headers.
-
Support: Core
properties:
add:
@@ -12705,18 +9905,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -12730,7 +9927,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -12762,18 +9958,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -12787,18 +9980,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -12812,7 +10002,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -12839,49 +10028,42 @@ spec:
x-kubernetes-list-type: map
type: object
requestMirror:
- description: |-
+ description: |+
RequestMirror defines a schema for a filter that mirrors requests.
Requests are sent to the specified destination, but responses from
that destination are ignored.
-
This filter can be used multiple times within the same rule. Note that
not all implementations will be able to support mirroring to multiple
backends.
-
Support: Extended
+
properties:
backendRef:
description: |-
BackendRef references a resource where mirrored requests are sent.
-
Mirrored requests must be sent only to a single destination endpoint
within this BackendRef, irrespective of how many endpoints are present
within this BackendRef.
-
If the referent cannot be found, this BackendRef is invalid and must be
dropped from the Gateway. The controller must ensure the "ResolvedRefs"
condition on the Route status is set to `status: False` and not configure
this backend in the underlying implementation.
-
If there is a cross-namespace reference to an *existing* object
that is not allowed by a ReferenceGrant, the controller must ensure the
"ResolvedRefs" condition on the Route is set to `status: False`,
with the "RefNotPermitted" reason and not configure this backend in the
underlying implementation.
-
In either error case, the Message of the `ResolvedRefs` Condition
should be used to provide more detail about the problem.
-
Support: Extended for Kubernetes Service
-
Support: Implementation-specific for any other resource
properties:
group:
@@ -12898,20 +10080,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -12927,13 +10105,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -12957,15 +10133,56 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind
== ''Service'') ? has(self.port) : true'
+ fraction:
+ description: |+
+ Fraction represents the fraction of requests that should be
+ mirrored to BackendRef.
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ properties:
+ denominator:
+ default: 100
+ format: int32
+ minimum: 1
+ type: integer
+ numerator:
+ format: int32
+ minimum: 0
+ type: integer
+ required:
+ - numerator
+ type: object
+ x-kubernetes-validations:
+ - message: numerator must be less than or equal
+ to denominator
+ rule: self.numerator <= self.denominator
+ percent:
+ description: |+
+ Percent represents the percentage of requests that should be
+ mirrored to BackendRef. Its minimum value is 0 (indicating 0% of
+ requests) and its maximum value is 100 (indicating 100% of requests).
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ format: int32
+ maximum: 100
+ minimum: 0
+ type: integer
required:
- backendRef
type: object
+ x-kubernetes-validations:
+ - message: Only one of percent or fraction may be
+ specified in HTTPRequestMirrorFilter
+ rule: '!(has(self.percent) && has(self.fraction))'
requestRedirect:
description: |-
RequestRedirect defines a schema for a filter that responds to the
request with an HTTP redirection.
-
Support: Core
properties:
hostname:
@@ -12974,7 +10191,6 @@ spec:
header in the response.
When empty, the hostname in the `Host` header of the request is used.
-
Support: Core
maxLength: 253
minLength: 1
@@ -12986,7 +10202,6 @@ spec:
The modified path is then used to construct the `Location` header. When
empty, the request path is used as-is.
-
Support: Extended
properties:
replaceFullPath:
@@ -13002,32 +10217,17 @@ spec:
to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch
of "/xyz" would be modified to "/xyz/bar".
-
Note that this matches the behavior of the PathPrefix match type. This
matches full path elements. A path element refers to the list of labels
in the path split by the `/` separator. When specified, a trailing `/` is
ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all
match the prefix `/abc`, but the path `/abcd` would not.
-
ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.
Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in
the implementation setting the Accepted Condition for the Route to `status: False`.
-
Request Path | Prefix Match | Replace Prefix | Modified Path
- -------------|--------------|----------------|----------
- /foo/bar | /foo | /xyz | /xyz/bar
- /foo/bar | /foo | /xyz/ | /xyz/bar
- /foo/bar | /foo/ | /xyz | /xyz/bar
- /foo/bar | /foo/ | /xyz/ | /xyz/bar
- /foo | /foo | /xyz | /xyz
- /foo/ | /foo | /xyz | /xyz/
- /foo/bar | /foo | | /bar
- /foo/ | /foo | | /
- /foo | /foo | | /
- /foo/ | /foo | / | /
- /foo | /foo | / | /
maxLength: 1024
type: string
type:
@@ -13035,11 +10235,9 @@ spec:
Type defines the type of path modifier. Additional types may be
added in a future release of the API.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -13072,11 +10270,9 @@ spec:
Port is the port to be used in the value of the `Location`
header in the response.
-
If no port is specified, the redirect port MUST be derived using the
following rules:
-
* If redirect scheme is not-empty, the redirect port MUST be the well-known
port associated with the redirect scheme. Specifically "http" to port 80
and "https" to port 443. If the redirect scheme does not have a
@@ -13084,17 +10280,14 @@ spec:
* If redirect scheme is empty, the redirect port MUST be the Gateway
Listener port.
-
Implementations SHOULD NOT add the port number in the 'Location'
header in the following cases:
-
* A Location header that will use HTTP (whether that is determined via
the Listener protocol or the Scheme field) _and_ use port 80.
* A Location header that will use HTTPS (whether that is determined via
the Listener protocol or the Scheme field) _and_ use port 443.
-
Support: Extended
format: int32
maximum: 65535
@@ -13105,20 +10298,16 @@ spec:
Scheme is the scheme to be used in the value of the `Location` header in
the response. When empty, the scheme of the request is used.
-
Scheme redirects can affect the port of the redirect, for more information,
refer to the documentation for the port field of this filter.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
-
Support: Extended
enum:
- http
@@ -13129,16 +10318,13 @@ spec:
description: |-
StatusCode is the HTTP status code to be used in response.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
-
Support: Core
enum:
- 301
@@ -13150,7 +10336,6 @@ spec:
ResponseHeaderModifier defines a schema for a filter that modifies response
headers.
-
Support: Extended
properties:
add:
@@ -13159,18 +10344,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -13184,7 +10366,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -13216,18 +10397,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -13241,18 +10419,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -13266,7 +10441,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -13297,17 +10471,14 @@ spec:
Type identifies the type of filter to apply. As with other API fields,
types are classified into three conformance levels:
-
- Core: Filter types and their corresponding configuration defined by
"Support: Core" in this package, e.g. "RequestHeaderModifier". All
implementations must support core filters.
-
- Extended: Filter types and their corresponding configuration defined by
"Support: Extended" in this package, e.g. "RequestMirror". Implementers
are encouraged to support extended filters.
-
- Implementation-specific: Filters that are defined and supported by
specific vendors.
In the future, filters showing convergence in behavior across multiple
@@ -13316,20 +10487,16 @@ spec:
is specified using the ExtensionRef field. `Type` should be set to
"ExtensionRef" for custom filters.
-
Implementers are encouraged to define custom implementation types to
extend the core API with implementation-specific behavior.
-
If a reference to a custom filter type cannot be resolved, the filter
MUST NOT be skipped. Instead, requests that would have been processed by
that filter MUST receive a HTTP error response.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -13345,7 +10512,6 @@ spec:
description: |-
URLRewrite defines a schema for a filter that modifies a request during forwarding.
-
Support: Extended
properties:
hostname:
@@ -13353,7 +10519,6 @@ spec:
Hostname is the value to be used to replace the Host header value during
forwarding.
-
Support: Extended
maxLength: 253
minLength: 1
@@ -13363,7 +10528,6 @@ spec:
description: |-
Path defines a path rewrite.
-
Support: Extended
properties:
replaceFullPath:
@@ -13379,32 +10543,17 @@ spec:
to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch
of "/xyz" would be modified to "/xyz/bar".
-
Note that this matches the behavior of the PathPrefix match type. This
matches full path elements. A path element refers to the list of labels
in the path split by the `/` separator. When specified, a trailing `/` is
ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all
match the prefix `/abc`, but the path `/abcd` would not.
-
ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.
Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in
the implementation setting the Accepted Condition for the Route to `status: False`.
-
Request Path | Prefix Match | Replace Prefix | Modified Path
- -------------|--------------|----------------|----------
- /foo/bar | /foo | /xyz | /xyz/bar
- /foo/bar | /foo | /xyz/ | /xyz/bar
- /foo/bar | /foo/ | /xyz | /xyz/bar
- /foo/bar | /foo/ | /xyz/ | /xyz/bar
- /foo | /foo | /xyz | /xyz
- /foo/ | /foo | /xyz | /xyz/
- /foo/bar | /foo | | /bar
- /foo/ | /foo | | /
- /foo | /foo | | /
- /foo/ | /foo | / | /
- /foo | /foo | / | /
maxLength: 1024
type: string
type:
@@ -13412,11 +10561,9 @@ spec:
Type defines the type of path modifier. Additional types may be
added in a future release of the API.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -13529,20 +10676,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -13558,13 +10701,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -13591,13 +10732,11 @@ spec:
implementation supports. Weight is not a percentage and the sum of
weights does not need to equal 100.
-
If only one backend is specified and it has a weight greater than 0, 100%
of the traffic is forwarded to that backend. If weight is set to 0, no
traffic should be forwarded for this entry. If unspecified, weight
defaults to 1.
-
Support for this field varies based on the context where used.
format: int32
maximum: 1000000
@@ -13617,37 +10756,30 @@ spec:
Filters define the filters that are applied to requests that match
this rule.
-
Wherever possible, implementations SHOULD implement filters in the order
they are specified.
-
Implementations MAY choose to implement this ordering strictly, rejecting
any combination or order of filters that can not be supported. If implementations
choose a strict interpretation of filter ordering, they MUST clearly document
that behavior.
-
To reject an invalid combination or order of filters, implementations SHOULD
consider the Route Rules with this configuration invalid. If all Route Rules
in a Route are invalid, the entire Route would be considered invalid. If only
a portion of Route Rules are invalid, implementations MUST set the
"PartiallyInvalid" condition for the Route.
-
Conformance-levels at this level are defined based on the type of filter:
-
- ALL core filters MUST be supported by all implementations.
- Implementers are encouraged to support extended filters.
- Implementation-specific custom filters have no API guarantees across
implementations.
-
Specifying the same filter multiple times is not supported unless explicitly
indicated in the filter.
-
All filters are expected to be compatible with each other except for the
URLRewrite and RequestRedirect filters, which may not be combined. If an
implementation can not support other combinations of filters, they must clearly
@@ -13656,7 +10788,6 @@ spec:
`False`, implementations may use the `IncompatibleFilters` reason to specify
this configuration error.
-
Support: Core
items:
description: |-
@@ -13674,10 +10805,8 @@ spec:
"networking.example.net"). ExtensionRef MUST NOT be used for core and
extended filters.
-
This filter can be used multiple times within the same rule.
-
Support: Implementation-specific
properties:
group:
@@ -13709,7 +10838,6 @@ spec:
RequestHeaderModifier defines a schema for a filter that modifies request
headers.
-
Support: Core
properties:
add:
@@ -13718,18 +10846,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -13742,7 +10867,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -13774,18 +10898,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -13799,18 +10920,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -13823,7 +10941,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -13850,49 +10967,42 @@ spec:
x-kubernetes-list-type: map
type: object
requestMirror:
- description: |-
+ description: |+
RequestMirror defines a schema for a filter that mirrors requests.
Requests are sent to the specified destination, but responses from
that destination are ignored.
-
This filter can be used multiple times within the same rule. Note that
not all implementations will be able to support mirroring to multiple
backends.
-
Support: Extended
+
properties:
backendRef:
description: |-
BackendRef references a resource where mirrored requests are sent.
-
Mirrored requests must be sent only to a single destination endpoint
within this BackendRef, irrespective of how many endpoints are present
within this BackendRef.
-
If the referent cannot be found, this BackendRef is invalid and must be
dropped from the Gateway. The controller must ensure the "ResolvedRefs"
condition on the Route status is set to `status: False` and not configure
this backend in the underlying implementation.
-
If there is a cross-namespace reference to an *existing* object
that is not allowed by a ReferenceGrant, the controller must ensure the
"ResolvedRefs" condition on the Route is set to `status: False`,
with the "RefNotPermitted" reason and not configure this backend in the
underlying implementation.
-
In either error case, the Message of the `ResolvedRefs` Condition
should be used to provide more detail about the problem.
-
Support: Extended for Kubernetes Service
-
Support: Implementation-specific for any other resource
properties:
group:
@@ -13909,20 +11019,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -13938,13 +11044,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -13968,15 +11072,56 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
+ fraction:
+ description: |+
+ Fraction represents the fraction of requests that should be
+ mirrored to BackendRef.
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ properties:
+ denominator:
+ default: 100
+ format: int32
+ minimum: 1
+ type: integer
+ numerator:
+ format: int32
+ minimum: 0
+ type: integer
+ required:
+ - numerator
+ type: object
+ x-kubernetes-validations:
+ - message: numerator must be less than or equal to
+ denominator
+ rule: self.numerator <= self.denominator
+ percent:
+ description: |+
+ Percent represents the percentage of requests that should be
+ mirrored to BackendRef. Its minimum value is 0 (indicating 0% of
+ requests) and its maximum value is 100 (indicating 100% of requests).
+
+ Only one of Fraction or Percent may be specified. If neither field
+ is specified, 100% of requests will be mirrored.
+
+ format: int32
+ maximum: 100
+ minimum: 0
+ type: integer
required:
- backendRef
type: object
+ x-kubernetes-validations:
+ - message: Only one of percent or fraction may be specified
+ in HTTPRequestMirrorFilter
+ rule: '!(has(self.percent) && has(self.fraction))'
requestRedirect:
description: |-
RequestRedirect defines a schema for a filter that responds to the
request with an HTTP redirection.
-
Support: Core
properties:
hostname:
@@ -13985,7 +11130,6 @@ spec:
header in the response.
When empty, the hostname in the `Host` header of the request is used.
-
Support: Core
maxLength: 253
minLength: 1
@@ -13997,7 +11141,6 @@ spec:
The modified path is then used to construct the `Location` header. When
empty, the request path is used as-is.
-
Support: Extended
properties:
replaceFullPath:
@@ -14013,32 +11156,17 @@ spec:
to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch
of "/xyz" would be modified to "/xyz/bar".
-
Note that this matches the behavior of the PathPrefix match type. This
matches full path elements. A path element refers to the list of labels
in the path split by the `/` separator. When specified, a trailing `/` is
ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all
match the prefix `/abc`, but the path `/abcd` would not.
-
ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.
Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in
the implementation setting the Accepted Condition for the Route to `status: False`.
-
Request Path | Prefix Match | Replace Prefix | Modified Path
- -------------|--------------|----------------|----------
- /foo/bar | /foo | /xyz | /xyz/bar
- /foo/bar | /foo | /xyz/ | /xyz/bar
- /foo/bar | /foo/ | /xyz | /xyz/bar
- /foo/bar | /foo/ | /xyz/ | /xyz/bar
- /foo | /foo | /xyz | /xyz
- /foo/ | /foo | /xyz | /xyz/
- /foo/bar | /foo | | /bar
- /foo/ | /foo | | /
- /foo | /foo | | /
- /foo/ | /foo | / | /
- /foo | /foo | / | /
maxLength: 1024
type: string
type:
@@ -14046,11 +11174,9 @@ spec:
Type defines the type of path modifier. Additional types may be
added in a future release of the API.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -14083,11 +11209,9 @@ spec:
Port is the port to be used in the value of the `Location`
header in the response.
-
If no port is specified, the redirect port MUST be derived using the
following rules:
-
* If redirect scheme is not-empty, the redirect port MUST be the well-known
port associated with the redirect scheme. Specifically "http" to port 80
and "https" to port 443. If the redirect scheme does not have a
@@ -14095,17 +11219,14 @@ spec:
* If redirect scheme is empty, the redirect port MUST be the Gateway
Listener port.
-
Implementations SHOULD NOT add the port number in the 'Location'
header in the following cases:
-
* A Location header that will use HTTP (whether that is determined via
the Listener protocol or the Scheme field) _and_ use port 80.
* A Location header that will use HTTPS (whether that is determined via
the Listener protocol or the Scheme field) _and_ use port 443.
-
Support: Extended
format: int32
maximum: 65535
@@ -14116,20 +11237,16 @@ spec:
Scheme is the scheme to be used in the value of the `Location` header in
the response. When empty, the scheme of the request is used.
-
Scheme redirects can affect the port of the redirect, for more information,
refer to the documentation for the port field of this filter.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
-
Support: Extended
enum:
- http
@@ -14140,16 +11257,13 @@ spec:
description: |-
StatusCode is the HTTP status code to be used in response.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
-
Support: Core
enum:
- 301
@@ -14161,7 +11275,6 @@ spec:
ResponseHeaderModifier defines a schema for a filter that modifies response
headers.
-
Support: Extended
properties:
add:
@@ -14170,18 +11283,15 @@ spec:
before the action. It appends to any existing values associated
with the header name.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
add:
- name: "my-header"
value: "bar,baz"
-
Output:
GET /foo HTTP/1.1
my-header: foo,bar,baz
@@ -14194,7 +11304,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -14226,18 +11335,15 @@ spec:
names are case-insensitive (see
https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
-
Input:
GET /foo HTTP/1.1
my-header1: foo
my-header2: bar
my-header3: baz
-
Config:
remove: ["my-header1", "my-header3"]
-
Output:
GET /foo HTTP/1.1
my-header2: bar
@@ -14251,18 +11357,15 @@ spec:
Set overwrites the request with the given header (name, value)
before the action.
-
Input:
GET /foo HTTP/1.1
my-header: foo
-
Config:
set:
- name: "my-header"
value: "bar"
-
Output:
GET /foo HTTP/1.1
my-header: bar
@@ -14275,7 +11378,6 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, the first entry with
an equivalent name MUST be considered for a match. Subsequent entries
with an equivalent header name MUST be ignored. Due to the
@@ -14306,17 +11408,14 @@ spec:
Type identifies the type of filter to apply. As with other API fields,
types are classified into three conformance levels:
-
- Core: Filter types and their corresponding configuration defined by
"Support: Core" in this package, e.g. "RequestHeaderModifier". All
implementations must support core filters.
-
- Extended: Filter types and their corresponding configuration defined by
"Support: Extended" in this package, e.g. "RequestMirror". Implementers
are encouraged to support extended filters.
-
- Implementation-specific: Filters that are defined and supported by
specific vendors.
In the future, filters showing convergence in behavior across multiple
@@ -14325,20 +11424,16 @@ spec:
is specified using the ExtensionRef field. `Type` should be set to
"ExtensionRef" for custom filters.
-
Implementers are encouraged to define custom implementation types to
extend the core API with implementation-specific behavior.
-
If a reference to a custom filter type cannot be resolved, the filter
MUST NOT be skipped. Instead, requests that would have been processed by
that filter MUST receive a HTTP error response.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -14354,7 +11449,6 @@ spec:
description: |-
URLRewrite defines a schema for a filter that modifies a request during forwarding.
-
Support: Extended
properties:
hostname:
@@ -14362,7 +11456,6 @@ spec:
Hostname is the value to be used to replace the Host header value during
forwarding.
-
Support: Extended
maxLength: 253
minLength: 1
@@ -14372,7 +11465,6 @@ spec:
description: |-
Path defines a path rewrite.
-
Support: Extended
properties:
replaceFullPath:
@@ -14388,32 +11480,17 @@ spec:
to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch
of "/xyz" would be modified to "/xyz/bar".
-
Note that this matches the behavior of the PathPrefix match type. This
matches full path elements. A path element refers to the list of labels
in the path split by the `/` separator. When specified, a trailing `/` is
ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all
match the prefix `/abc`, but the path `/abcd` would not.
-
ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.
Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in
the implementation setting the Accepted Condition for the Route to `status: False`.
-
Request Path | Prefix Match | Replace Prefix | Modified Path
- -------------|--------------|----------------|----------
- /foo/bar | /foo | /xyz | /xyz/bar
- /foo/bar | /foo | /xyz/ | /xyz/bar
- /foo/bar | /foo/ | /xyz | /xyz/bar
- /foo/bar | /foo/ | /xyz/ | /xyz/bar
- /foo | /foo | /xyz | /xyz
- /foo/ | /foo | /xyz | /xyz/
- /foo/bar | /foo | | /bar
- /foo/ | /foo | | /
- /foo | /foo | | /
- /foo/ | /foo | / | /
- /foo | /foo | / | /
maxLength: 1024
type: string
type:
@@ -14421,11 +11498,9 @@ spec:
Type defines the type of path modifier. Additional types may be
added in a future release of the API.
-
Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.
-
Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
@@ -14526,10 +11601,8 @@ spec:
HTTP requests. Each match is independent, i.e. this rule will be matched
if **any** one of the matches is satisfied.
-
For example, take the following matches configuration:
-
```
matches:
- path:
@@ -14541,65 +11614,54 @@ spec:
value: "/v2/foo"
```
-
For a request to match against this rule, a request must satisfy
EITHER of the two conditions:
-
- path prefixed with `/foo` AND contains the header `version: v2`
- path prefix of `/v2/foo`
-
See the documentation for HTTPRouteMatch on how to specify multiple
match conditions that should be ANDed together.
-
If no matches are specified, the default is a prefix
path match on "/", which has the effect of matching every
HTTP request.
-
Proxy or Load Balancer routing configuration generated from HTTPRoutes
MUST prioritize matches based on the following criteria, continuing on
ties. Across all rules specified on applicable Routes, precedence must be
given to the match having:
-
* "Exact" path match.
* "Prefix" path match with largest number of characters.
* Method match.
* Largest number of header matches.
* Largest number of query param matches.
-
Note: The precedence of RegularExpression path matches are implementation-specific.
-
If ties still exist across multiple Routes, matching precedence MUST be
determined in order of the following criteria, continuing on ties:
-
* The oldest Route based on creation timestamp.
* The Route appearing first in alphabetical order by
"{namespace}/{name}".
-
If ties still exist within an HTTPRoute, matching precedence MUST be granted
to the FIRST matching rule (in list order) with a match meeting the above
criteria.
-
When no rules matching a request have been successfully attached to the
parent a request is coming from, a HTTP 404 status code MUST be returned.
items:
description: "HTTPRouteMatch defines the predicate used to
match requests to a given\naction. Multiple match types
are ANDed together, i.e. the match will\nevaluate to true
- only if all conditions are satisfied.\n\n\nFor example,
- the match below will match a HTTP request only if its path\nstarts
- with `/foo` AND it contains the `version: v1` header:\n\n\n```\nmatch:\n\n\n\tpath:\n\t
+ only if all conditions are satisfied.\n\nFor example, the
+ match below will match a HTTP request only if its path\nstarts
+ with `/foo` AND it contains the `version: v1` header:\n\n```\nmatch:\n\n\tpath:\n\t
\ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t
- \ value \"v1\"\n\n\n```"
+ \ value \"v1\"\n\n```"
properties:
headers:
description: |-
@@ -14616,14 +11678,12 @@ spec:
Name is the name of the HTTP Header to be matched. Name matching MUST be
case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
-
If multiple entries specify equivalent header names, only the first
entry with an equivalent name MUST be considered for a match. Subsequent
entries with an equivalent header name MUST be ignored. Due to the
case-insensitivity of header names, "foo" and "Foo" are considered
equivalent.
-
When a header is repeated in an HTTP request, it is
implementation-specific behavior as to how this is represented.
Generally, proxies should follow the guidance from the RFC:
@@ -14638,13 +11698,10 @@ spec:
description: |-
Type specifies how to match against the value of the header.
-
Support: Core (Exact)
-
Support: Implementation-specific (RegularExpression)
-
Since RegularExpression HeaderMatchType has implementation-specific
conformance, implementations can support POSIX, PCRE or any other dialects
of regular expressions. Please read the implementation's documentation to
@@ -14674,7 +11731,6 @@ spec:
When specified, this route will be matched only if the request has the
specified method.
-
Support: Extended
enum:
- GET
@@ -14700,10 +11756,8 @@ spec:
description: |-
Type specifies how to match against the path Value.
-
Support: Core (Exact, PathPrefix)
-
Support: Implementation-specific (RegularExpression)
enum:
- Exact
@@ -14768,7 +11822,6 @@ spec:
values are ANDed together, meaning, a request must match all the
specified query parameters to select the route.
-
Support: Extended
items:
description: |-
@@ -14781,12 +11834,10 @@ spec:
exact string match. (See
https://tools.ietf.org/html/rfc7230#section-2.7.3).
-
If multiple entries specify equivalent query param names, only the first
entry with an equivalent name MUST be considered for a match. Subsequent
entries with an equivalent query param name MUST be ignored.
-
If a query param is repeated in an HTTP request, the behavior is
purposely left undefined, since different data planes have different
capabilities. However, it is *recommended* that implementations should
@@ -14794,7 +11845,6 @@ spec:
as this behavior is expected in other load balancing contexts outside of
the Gateway API.
-
Users SHOULD NOT route traffic based on repeated query params to guard
themselves against potential differences in the implementations.
maxLength: 256
@@ -14806,13 +11856,10 @@ spec:
description: |-
Type specifies how to match against the value of the query parameter.
-
Support: Extended (Exact)
-
Support: Implementation-specific (RegularExpression)
-
Since RegularExpression QueryParamMatchType has Implementation-specific
conformance, implementations can support POSIX, PCRE or any other
dialects of regular expressions. Please read the implementation's
@@ -14837,17 +11884,114 @@ spec:
- name
x-kubernetes-list-type: map
type: object
- maxItems: 8
+ maxItems: 64
type: array
+ name:
+ description: |
+ Name is the name of the route rule. This name MUST be unique within a Route if it is set.
+
+ Support: Extended
+ maxLength: 253
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ retry:
+ description: |+
+ Retry defines the configuration for when to retry an HTTP request.
+
+ Support: Extended
+
+ properties:
+ attempts:
+ description: |-
+ Attempts specifies the maxmimum number of times an individual request
+ from the gateway to a backend should be retried.
+
+ If the maximum number of retries has been attempted without a successful
+ response from the backend, the Gateway MUST return an error.
+
+ When this field is unspecified, the number of times to attempt to retry
+ a backend request is implementation-specific.
+
+ Support: Extended
+ type: integer
+ backoff:
+ description: |-
+ Backoff specifies the minimum duration a Gateway should wait between
+ retry attempts and is represented in Gateway API Duration formatting.
+
+ For example, setting the `rules[].retry.backoff` field to the value
+ `100ms` will cause a backend request to first be retried approximately
+ 100 milliseconds after timing out or receiving a response code configured
+ to be retryable.
+
+ An implementation MAY use an exponential or alternative backoff strategy
+ for subsequent retry attempts, MAY cap the maximum backoff duration to
+ some amount greater than the specified minimum, and MAY add arbitrary
+ jitter to stagger requests, as long as unsuccessful backend requests are
+ not retried before the configured minimum duration.
+
+ If a Request timeout (`rules[].timeouts.request`) is configured on the
+ route, the entire duration of the initial request and any retry attempts
+ MUST not exceed the Request timeout duration. If any retry attempts are
+ still in progress when the Request timeout duration has been reached,
+ these SHOULD be canceled if possible and the Gateway MUST immediately
+ return a timeout error.
+
+ If a BackendRequest timeout (`rules[].timeouts.backendRequest`) is
+ configured on the route, any retry attempts which reach the configured
+ BackendRequest timeout duration without a response SHOULD be canceled if
+ possible and the Gateway should wait for at least the specified backoff
+ duration before attempting to retry the backend request again.
+
+ If a BackendRequest timeout is _not_ configured on the route, retry
+ attempts MAY time out after an implementation default duration, or MAY
+ remain pending until a configured Request timeout or implementation
+ default duration for total request time is reached.
+
+ When this field is unspecified, the time to wait between retry attempts
+ is implementation-specific.
+
+ Support: Extended
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ codes:
+ description: |-
+ Codes defines the HTTP response status codes for which a backend request
+ should be retried.
+
+ Support: Extended
+ items:
+ description: |-
+ HTTPRouteRetryStatusCode defines an HTTP response status code for
+ which a backend request should be retried.
+
+ Implementations MUST support the following status codes as retryable:
+
+ * 500
+ * 502
+ * 503
+ * 504
+
+ Implementations MAY support specifying additional discrete values in the
+ 500-599 range.
+
+ Implementations MAY support specifying discrete values in the 400-499 range,
+ which are often inadvisable to retry.
+
+
+ maximum: 599
+ minimum: 400
+ type: integer
+ type: array
+ type: object
sessionPersistence:
description: |+
SessionPersistence defines and configures session persistence
for the route rule.
-
Support: Extended
-
properties:
absoluteTimeout:
description: |-
@@ -14855,7 +11999,6 @@ spec:
session. Once the AbsoluteTimeout duration has elapsed, the
session becomes invalid.
-
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
@@ -14864,7 +12007,6 @@ spec:
CookieConfig provides configuration settings that are specific
to cookie-based session persistence.
-
Support: Core
properties:
lifetimeType:
@@ -14876,20 +12018,16 @@ spec:
attributes, while a session cookie is deleted when the current
session ends.
-
When set to "Permanent", AbsoluteTimeout indicates the
cookie's lifetime via the Expires or Max-Age cookie attributes
and is required.
-
When set to "Session", AbsoluteTimeout indicates the
absolute lifetime of the cookie tracked by the gateway and
is optional.
-
Support: Core for "Session" type
-
Support: Extended for "Permanent" type
enum:
- Permanent
@@ -14902,7 +12040,6 @@ spec:
Once the session has been idle for more than the specified
IdleTimeout duration, the session becomes invalid.
-
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
@@ -14913,7 +12050,6 @@ spec:
should avoid reusing session names to prevent unintended
consequences, such as rejection or unpredictable behavior.
-
Support: Implementation-specific
maxLength: 128
type: string
@@ -14924,10 +12060,8 @@ spec:
the use a header or cookie. Defaults to cookie based session
persistence.
-
Support: Core for "Cookie" type
-
Support: Extended for "Header" type
enum:
- Cookie
@@ -14937,16 +12071,13 @@ spec:
x-kubernetes-validations:
- message: AbsoluteTimeout must be specified when cookie lifetimeType
is Permanent
- rule: '!has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType
- != ''Permanent'' || has(self.absoluteTimeout)'
+ rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType)
+ || self.cookieConfig.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)'
timeouts:
- description: |+
+ description: |-
Timeouts defines the timeouts that can be configured for an HTTP request.
-
Support: Extended
-
-
properties:
backendRequest:
description: |-
@@ -14954,21 +12085,19 @@ spec:
to a backend. This covers the time from when the request first starts being
sent from the gateway to when the full response has been received from the backend.
-
Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout
completely. Implementations that cannot completely disable the timeout MUST
instead interpret the zero duration as the longest possible value to which
the timeout can be set.
-
An entire client HTTP transaction with a gateway, covered by the Request timeout,
may result in more than one call from the gateway to the destination backend,
for example, if automatic retries are supported.
-
- Because the Request timeout encompasses the BackendRequest timeout, the value of
- BackendRequest must be <= the value of Request timeout.
-
+ The value of BackendRequest must be a Gateway API Duration string as defined by
+ GEP-2257. When this field is unspecified, its behavior is implementation-specific;
+ when specified, the value of BackendRequest must be no more than the value of the
+ Request timeout (since the Request timeout encompasses the BackendRequest timeout).
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
@@ -14979,26 +12108,22 @@ spec:
If the gateway has not been able to respond before this deadline is met, the gateway
MUST return a timeout error.
-
For example, setting the `rules.timeouts.request` field to the value `10s` in an
`HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds
to complete.
-
Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout
completely. Implementations that cannot completely disable the timeout MUST
instead interpret the zero duration as the longest possible value to which
the timeout can be set.
-
This timeout is intended to cover as close to the whole request-response transaction
as possible although an implementation MAY choose to start the timeout after the entire
request stream has been received instead of immediately after the transaction is
initiated by the client.
-
- When this field is unspecified, request timeout behavior is implementation-specific.
-
+ The value of Request is a Gateway API Duration string as defined by GEP-2257. When this
+ field is unspecified, request timeout behavior is implementation-specific.
Support: Extended
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
@@ -15053,6 +12178,24 @@ spec:
!= ''PathPrefix'') ? false : true) : true'
maxItems: 16
type: array
+ x-kubernetes-validations:
+ - message: While 16 rules and 64 matches per rule are allowed, the
+ total number of matches across all rules in a route must be less
+ than 128
+ rule: '(self.size() > 0 ? self[0].matches.size() : 0) + (self.size()
+ > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size()
+ : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size()
+ > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size()
+ : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size()
+ > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size()
+ : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size()
+ > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size()
+ : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size()
+ > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size()
+ : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128'
+ - message: Rule name must be unique within the route
+ rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)
+ && l1.name == l2.name))
type: object
status:
description: Status defines the current state of HTTPRoute.
@@ -15066,13 +12209,11 @@ spec:
first sees the route and should update the entry as appropriate when the
route or gateway is modified.
-
Note that parent references that cannot be resolved by an implementation
of this API will not be added to this list. Implementations of this API
can only populate Route status for the Gateways/parent resources they are
responsible for.
-
A maximum of 32 Gateways will be represented in this list. An empty list
means the route has not been attached to any Gateway.
items:
@@ -15086,38 +12227,24 @@ spec:
Note that the route's availability is also subject to the Gateway's own
status conditions and listener status.
-
If the Route's ParentRef specifies an existing Gateway that supports
Routes of this kind AND that Gateway's controller has sufficient access,
then that Gateway's controller MUST set the "Accepted" condition on the
Route, to indicate whether the route has been accepted or rejected by the
Gateway, and why.
-
A Route MUST be considered "Accepted" if at least one of the Route's
rules is implemented by the Gateway.
-
There are a number of cases where the "Accepted" condition may not be set
due to lack of controller visibility, that includes when:
-
* The Route refers to a non-existent parent.
* The Route is of a type that the controller does not support.
* The Route is in a namespace the controller does not have access to.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -15159,12 +12286,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -15187,15 +12309,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
@@ -15216,7 +12335,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -15226,14 +12344,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -15243,7 +12358,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -15253,7 +12367,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -15261,12 +12374,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -15274,7 +12385,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -15285,7 +12395,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -15295,18 +12404,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -15315,7 +12421,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -15326,7 +12431,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -15334,12 +12438,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -15349,7 +12451,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -15388,8 +12489,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
- gateway.networking.k8s.io/bundle-version: v1.1.0
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+ gateway.networking.k8s.io/bundle-version: v1.2.1
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: referencegrants.gateway.networking.k8s.io
@@ -15406,187 +12507,6 @@ spec:
singular: referencegrant
scope: Namespaced
versions:
- - additionalPrinterColumns:
- - jsonPath: .metadata.creationTimestamp
- name: Age
- type: date
- deprecated: true
- deprecationWarning: The v1alpha2 version of ReferenceGrant has been deprecated
- and will be removed in a future release of the API. Please upgrade to v1beta1.
- name: v1alpha2
- schema:
- openAPIV3Schema:
- description: |-
- ReferenceGrant identifies kinds of resources in other namespaces that are
- trusted to reference the specified kinds of resources in the same namespace
- as the policy.
-
-
- Each ReferenceGrant can be used to represent a unique trust relationship.
- Additional Reference Grants can be used to add to the set of trusted
- sources of inbound references for the namespace they are defined within.
-
-
- A ReferenceGrant is required for all cross-namespace references in Gateway API
- (with the exception of cross-namespace Route-Gateway attachment, which is
- governed by the AllowedRoutes configuration on the Gateway, and cross-namespace
- Service ParentRefs on a "consumer" mesh Route, which defines routing rules
- applicable only to workloads in the Route namespace). ReferenceGrants allowing
- a reference from a Route to a Service are only applicable to BackendRefs.
-
-
- ReferenceGrant is a form of runtime verification allowing users to assert
- which cross-namespace object references are permitted. Implementations that
- support ReferenceGrant MUST NOT permit cross-namespace references which have
- no grant, and MUST respond to the removal of a grant by revoking the access
- that the grant allowed.
- properties:
- apiVersion:
- description: |-
- APIVersion defines the versioned schema of this representation of an object.
- Servers should convert recognized schemas to the latest internal value, and
- may reject unrecognized values.
- More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
- type: string
- kind:
- description: |-
- Kind is a string value representing the REST resource this object represents.
- Servers may infer this from the endpoint the client submits requests to.
- Cannot be updated.
- In CamelCase.
- More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
- type: string
- metadata:
- type: object
- spec:
- description: Spec defines the desired state of ReferenceGrant.
- properties:
- from:
- description: |-
- From describes the trusted namespaces and kinds that can reference the
- resources described in "To". Each entry in this list MUST be considered
- to be an additional place that references can be valid from, or to put
- this another way, entries MUST be combined using OR.
-
-
- Support: Core
- items:
- description: ReferenceGrantFrom describes trusted namespaces and
- kinds.
- properties:
- group:
- description: |-
- Group is the group of the referent.
- When empty, the Kubernetes core API group is inferred.
-
-
- Support: Core
- maxLength: 253
- pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- kind:
- description: |-
- Kind is the kind of the referent. Although implementations may support
- additional resources, the following types are part of the "Core"
- support level for this field.
-
-
- When used to permit a SecretObjectReference:
-
-
- * Gateway
-
-
- When used to permit a BackendObjectReference:
-
-
- * GRPCRoute
- * HTTPRoute
- * TCPRoute
- * TLSRoute
- * UDPRoute
- maxLength: 63
- minLength: 1
- pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
- type: string
- namespace:
- description: |-
- Namespace is the namespace of the referent.
-
-
- Support: Core
- maxLength: 63
- minLength: 1
- pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
- type: string
- required:
- - group
- - kind
- - namespace
- type: object
- maxItems: 16
- minItems: 1
- type: array
- to:
- description: |-
- To describes the resources that may be referenced by the resources
- described in "From". Each entry in this list MUST be considered to be an
- additional place that references can be valid to, or to put this another
- way, entries MUST be combined using OR.
-
-
- Support: Core
- items:
- description: |-
- ReferenceGrantTo describes what Kinds are allowed as targets of the
- references.
- properties:
- group:
- description: |-
- Group is the group of the referent.
- When empty, the Kubernetes core API group is inferred.
-
-
- Support: Core
- maxLength: 253
- pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
- type: string
- kind:
- description: |-
- Kind is the kind of the referent. Although implementations may support
- additional resources, the following types are part of the "Core"
- support level for this field:
-
-
- * Secret when used to permit a SecretObjectReference
- * Service when used to permit a BackendObjectReference
- maxLength: 63
- minLength: 1
- pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
- type: string
- name:
- description: |-
- Name is the name of the referent. When unspecified, this policy
- refers to all resources of the specified Group and Kind in the local
- namespace.
- maxLength: 253
- minLength: 1
- type: string
- required:
- - group
- - kind
- type: object
- maxItems: 16
- minItems: 1
- type: array
- required:
- - from
- - to
- type: object
- type: object
- served: true
- storage: false
- subresources: {}
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
@@ -15599,16 +12519,13 @@ spec:
trusted to reference the specified kinds of resources in the same namespace
as the policy.
-
Each ReferenceGrant can be used to represent a unique trust relationship.
Additional Reference Grants can be used to add to the set of trusted
sources of inbound references for the namespace they are defined within.
-
All cross-namespace references in Gateway API (with the exception of cross-namespace
Gateway-route attachment) require a ReferenceGrant.
-
ReferenceGrant is a form of runtime verification allowing users to assert
which cross-namespace object references are permitted. Implementations that
support ReferenceGrant MUST NOT permit cross-namespace references which have
@@ -15642,7 +12559,6 @@ spec:
to be an additional place that references can be valid from, or to put
this another way, entries MUST be combined using OR.
-
Support: Core
items:
description: ReferenceGrantFrom describes trusted namespaces and
@@ -15653,7 +12569,6 @@ spec:
Group is the group of the referent.
When empty, the Kubernetes core API group is inferred.
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -15664,16 +12579,12 @@ spec:
additional resources, the following types are part of the "Core"
support level for this field.
-
When used to permit a SecretObjectReference:
-
* Gateway
-
When used to permit a BackendObjectReference:
-
* GRPCRoute
* HTTPRoute
* TCPRoute
@@ -15687,7 +12598,6 @@ spec:
description: |-
Namespace is the namespace of the referent.
-
Support: Core
maxLength: 63
minLength: 1
@@ -15708,7 +12618,6 @@ spec:
additional place that references can be valid to, or to put this another
way, entries MUST be combined using OR.
-
Support: Core
items:
description: |-
@@ -15720,7 +12629,6 @@ spec:
Group is the group of the referent.
When empty, the Kubernetes core API group is inferred.
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -15731,7 +12639,6 @@ spec:
additional resources, the following types are part of the "Core"
support level for this field:
-
* Secret when used to permit a SecretObjectReference
* Service when used to permit a BackendObjectReference
maxLength: 63
@@ -15775,8 +12682,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
- gateway.networking.k8s.io/bundle-version: v1.1.0
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+ gateway.networking.k8s.io/bundle-version: v1.2.1
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: tcproutes.gateway.networking.k8s.io
@@ -15836,21 +12743,16 @@ spec:
create a "producer" route for a Service in a different namespace from the
Route.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
ParentRefs must be _distinct_. This means either that:
-
* They select different objects. If this is the case, then parentRef
entries are distinct. In terms of fields, this means that the
multi-part key defined by `group`, `kind`, `namespace`, and `name` must
@@ -15860,10 +12762,8 @@ spec:
optional fields to different values. If one ParentRef sets a
combination of optional fields, all must set the same combination.
-
Some examples:
-
* If one ParentRef sets `sectionName`, all ParentRefs referencing the
same object must also set `sectionName`.
* If one ParentRef sets `port`, all ParentRefs referencing the same
@@ -15871,14 +12771,12 @@ spec:
* If one ParentRef sets `sectionName` and `port`, all ParentRefs
referencing the same object must also set `sectionName` and `port`.
-
It is possible to separately reference multiple distinct objects that may
be collapsed by an implementation. For example, some implementations may
choose to merge compatible Gateway Listeners together. If that is the
case, the list of routes attached to those resources should also be
merged.
-
Note that for ParentRefs that cross namespace boundaries, there are specific
rules. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example,
@@ -15886,12 +12784,10 @@ spec:
generic way to enable other kinds of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -15902,22 +12798,18 @@ spec:
-
items:
description: |-
ParentReference identifies an API object (usually a Gateway) that can be considered
a parent of this resource (usually a route). There are two kinds of parent resources
with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
properties:
@@ -15929,7 +12821,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -15939,14 +12830,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -15956,7 +12844,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -15966,7 +12853,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -15974,12 +12860,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -15987,7 +12871,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -15998,7 +12881,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -16008,18 +12890,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -16028,7 +12907,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -16039,7 +12917,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -16047,12 +12924,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -16062,7 +12937,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -16097,7 +12971,9 @@ spec:
|| p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port
== p2.port))))
rules:
- description: Rules are a list of TCP matchers and actions.
+ description: |+
+ Rules are a list of TCP matchers and actions.
+
items:
description: TCPRouteRule is the configuration for a given rule.
properties:
@@ -16110,53 +12986,41 @@ spec:
respect weight; if an invalid backend is requested to have 80% of
connections, then 80% of connections must be rejected instead.
-
Support: Core for Kubernetes Service
-
Support: Extended for Kubernetes ServiceImport
-
Support: Implementation-specific for any other resource
-
Support for weight: Extended
items:
description: |-
BackendRef defines how a Route should forward a request to a Kubernetes
resource.
-
Note that when a namespace different than the local namespace is specified, a
ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
-
When the BackendRef points to a Kubernetes Service, implementations SHOULD
honor the appProtocol field if it is set for the target Service Port.
-
Implementations supporting appProtocol SHOULD recognize the Kubernetes
Standard Application Protocols defined in KEP-3726.
-
If a Service appProtocol isn't specified, an implementation MAY infer the
backend protocol through its own means. Implementations MAY infer the
protocol from the Route type referring to the backend Service.
-
If a Route is not able to send traffic to the backend using the specified
protocol then the backend is considered invalid. Implementations MUST set the
"ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason.
-
-
Note that when the BackendTLSPolicy object is enabled by the implementation,
there are some extra rules about validity to consider here. See the fields
where this struct is used for more information about the exact behavior.
@@ -16175,20 +13039,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -16204,13 +13064,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -16237,13 +13095,11 @@ spec:
implementation supports. Weight is not a percentage and the sum of
weights does not need to equal 100.
-
If only one backend is specified and it has a weight greater than 0, 100%
of the traffic is forwarded to that backend. If weight is set to 0, no
traffic should be forwarded for this entry. If unspecified, weight
defaults to 1.
-
Support for this field varies based on the context where used.
format: int32
maximum: 1000000
@@ -16259,10 +13115,23 @@ spec:
maxItems: 16
minItems: 1
type: array
+ name:
+ description: |-
+ Name is the name of the route rule. This name MUST be unique within a Route if it is set.
+
+ Support: Extended
+ maxLength: 253
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
type: object
maxItems: 16
minItems: 1
type: array
+ x-kubernetes-validations:
+ - message: Rule name must be unique within the route
+ rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)
+ && l1.name == l2.name))
required:
- rules
type: object
@@ -16278,13 +13147,11 @@ spec:
first sees the route and should update the entry as appropriate when the
route or gateway is modified.
-
Note that parent references that cannot be resolved by an implementation
of this API will not be added to this list. Implementations of this API
can only populate Route status for the Gateways/parent resources they are
responsible for.
-
A maximum of 32 Gateways will be represented in this list. An empty list
means the route has not been attached to any Gateway.
items:
@@ -16298,38 +13165,24 @@ spec:
Note that the route's availability is also subject to the Gateway's own
status conditions and listener status.
-
If the Route's ParentRef specifies an existing Gateway that supports
Routes of this kind AND that Gateway's controller has sufficient access,
then that Gateway's controller MUST set the "Accepted" condition on the
Route, to indicate whether the route has been accepted or rejected by the
Gateway, and why.
-
A Route MUST be considered "Accepted" if at least one of the Route's
rules is implemented by the Gateway.
-
There are a number of cases where the "Accepted" condition may not be set
due to lack of controller visibility, that includes when:
-
* The Route refers to a non-existent parent.
* The Route is of a type that the controller does not support.
* The Route is in a namespace the controller does not have access to.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -16371,12 +13224,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -16399,15 +13247,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
@@ -16428,7 +13273,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -16438,14 +13282,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -16455,7 +13296,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -16465,7 +13305,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -16473,12 +13312,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -16486,7 +13323,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -16497,7 +13333,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -16507,18 +13342,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -16527,7 +13359,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -16538,7 +13369,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -16546,12 +13376,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -16561,7 +13389,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -16600,8 +13427,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
- gateway.networking.k8s.io/bundle-version: v1.1.0
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+ gateway.networking.k8s.io/bundle-version: v1.2.1
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: tlsroutes.gateway.networking.k8s.io
@@ -16628,7 +13455,6 @@ spec:
to match against TLS-specific metadata. This allows more flexibility
in matching streams for a given TLS listener.
-
If you need to forward traffic to a single target for a TLS listener, you
could choose to use a TCPRoute with a TLS listener.
properties:
@@ -16658,17 +13484,14 @@ spec:
SNI attribute of TLS ClientHello message in TLS handshake. This matches
the RFC 1123 definition of a hostname with 2 notable exceptions:
-
1. IPs are not allowed in SNI names per RFC 6066.
2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
label must appear by itself as the first label.
-
If a hostname is specified by both the Listener and TLSRoute, there
must be at least one intersecting hostname for the TLSRoute to be
attached to the Listener. For example:
-
* A Listener with `test.example.com` as the hostname matches TLSRoutes
that have either not specified any hostnames, or have specified at
least one of `test.example.com` or `*.example.com`.
@@ -16678,37 +13501,31 @@ spec:
`test.example.com` and `*.example.com` would both match. On the other
hand, `example.com` and `test.example.net` would not match.
-
If both the Listener and TLSRoute have specified hostnames, any
TLSRoute hostnames that do not match the Listener hostname MUST be
ignored. For example, if a Listener specified `*.example.com`, and the
TLSRoute specified `test.example.com` and `test.example.net`,
`test.example.net` must not be considered for a match.
-
If both the Listener and TLSRoute have specified hostnames, and none
match with the criteria above, then the TLSRoute is not accepted. The
implementation must raise an 'Accepted' Condition with a status of
`False` in the corresponding RouteParentStatus.
-
Support: Core
items:
description: |-
Hostname is the fully qualified domain name of a network host. This matches
the RFC 1123 definition of a hostname with 2 notable exceptions:
-
1. IPs are not allowed.
2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
label must appear by itself as the first label.
-
Hostname can be "precise" which is a domain name without the terminating
dot of a network host (e.g. "foo.example.com") or "wildcard", which is a
domain name prefixed with a single wildcard label (e.g. `*.example.com`).
-
Note that as per RFC1035 and RFC1123, a *label* must consist of lower case
alphanumeric characters or '-', and must start and end with an alphanumeric
character. No other punctuation is allowed.
@@ -16731,21 +13548,16 @@ spec:
create a "producer" route for a Service in a different namespace from the
Route.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
ParentRefs must be _distinct_. This means either that:
-
* They select different objects. If this is the case, then parentRef
entries are distinct. In terms of fields, this means that the
multi-part key defined by `group`, `kind`, `namespace`, and `name` must
@@ -16755,10 +13567,8 @@ spec:
optional fields to different values. If one ParentRef sets a
combination of optional fields, all must set the same combination.
-
Some examples:
-
* If one ParentRef sets `sectionName`, all ParentRefs referencing the
same object must also set `sectionName`.
* If one ParentRef sets `port`, all ParentRefs referencing the same
@@ -16766,14 +13576,12 @@ spec:
* If one ParentRef sets `sectionName` and `port`, all ParentRefs
referencing the same object must also set `sectionName` and `port`.
-
It is possible to separately reference multiple distinct objects that may
be collapsed by an implementation. For example, some implementations may
choose to merge compatible Gateway Listeners together. If that is the
case, the list of routes attached to those resources should also be
merged.
-
Note that for ParentRefs that cross namespace boundaries, there are specific
rules. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example,
@@ -16781,12 +13589,10 @@ spec:
generic way to enable other kinds of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -16797,22 +13603,18 @@ spec:
-
items:
description: |-
ParentReference identifies an API object (usually a Gateway) that can be considered
a parent of this resource (usually a route). There are two kinds of parent resources
with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
properties:
@@ -16824,7 +13626,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -16834,14 +13635,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -16851,7 +13649,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -16861,7 +13658,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -16869,12 +13665,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -16882,7 +13676,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -16893,7 +13686,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -16903,18 +13695,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -16923,7 +13712,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -16934,7 +13722,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -16942,12 +13729,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -16957,7 +13742,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -16992,7 +13776,9 @@ spec:
|| p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port
== p2.port))))
rules:
- description: Rules are a list of TLS matchers and actions.
+ description: |+
+ Rules are a list of TLS matchers and actions.
+
items:
description: TLSRouteRule is the configuration for a given rule.
properties:
@@ -17008,53 +13794,41 @@ spec:
requested to have 80% of requests, then 80% of requests must be rejected
instead.
-
Support: Core for Kubernetes Service
-
Support: Extended for Kubernetes ServiceImport
-
Support: Implementation-specific for any other resource
-
Support for weight: Extended
items:
description: |-
BackendRef defines how a Route should forward a request to a Kubernetes
resource.
-
Note that when a namespace different than the local namespace is specified, a
ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
-
When the BackendRef points to a Kubernetes Service, implementations SHOULD
honor the appProtocol field if it is set for the target Service Port.
-
Implementations supporting appProtocol SHOULD recognize the Kubernetes
Standard Application Protocols defined in KEP-3726.
-
If a Service appProtocol isn't specified, an implementation MAY infer the
backend protocol through its own means. Implementations MAY infer the
protocol from the Route type referring to the backend Service.
-
If a Route is not able to send traffic to the backend using the specified
protocol then the backend is considered invalid. Implementations MUST set the
"ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason.
-
-
Note that when the BackendTLSPolicy object is enabled by the implementation,
there are some extra rules about validity to consider here. See the fields
where this struct is used for more information about the exact behavior.
@@ -17073,20 +13847,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -17102,13 +13872,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -17135,13 +13903,11 @@ spec:
implementation supports. Weight is not a percentage and the sum of
weights does not need to equal 100.
-
If only one backend is specified and it has a weight greater than 0, 100%
of the traffic is forwarded to that backend. If weight is set to 0, no
traffic should be forwarded for this entry. If unspecified, weight
defaults to 1.
-
Support for this field varies based on the context where used.
format: int32
maximum: 1000000
@@ -17157,10 +13923,23 @@ spec:
maxItems: 16
minItems: 1
type: array
+ name:
+ description: |-
+ Name is the name of the route rule. This name MUST be unique within a Route if it is set.
+
+ Support: Extended
+ maxLength: 253
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
type: object
maxItems: 16
minItems: 1
type: array
+ x-kubernetes-validations:
+ - message: Rule name must be unique within the route
+ rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)
+ && l1.name == l2.name))
required:
- rules
type: object
@@ -17176,13 +13955,11 @@ spec:
first sees the route and should update the entry as appropriate when the
route or gateway is modified.
-
Note that parent references that cannot be resolved by an implementation
of this API will not be added to this list. Implementations of this API
can only populate Route status for the Gateways/parent resources they are
responsible for.
-
A maximum of 32 Gateways will be represented in this list. An empty list
means the route has not been attached to any Gateway.
items:
@@ -17196,38 +13973,24 @@ spec:
Note that the route's availability is also subject to the Gateway's own
status conditions and listener status.
-
If the Route's ParentRef specifies an existing Gateway that supports
Routes of this kind AND that Gateway's controller has sufficient access,
then that Gateway's controller MUST set the "Accepted" condition on the
Route, to indicate whether the route has been accepted or rejected by the
Gateway, and why.
-
A Route MUST be considered "Accepted" if at least one of the Route's
rules is implemented by the Gateway.
-
There are a number of cases where the "Accepted" condition may not be set
due to lack of controller visibility, that includes when:
-
* The Route refers to a non-existent parent.
* The Route is of a type that the controller does not support.
* The Route is in a namespace the controller does not have access to.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -17269,12 +14032,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -17297,15 +14055,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
@@ -17326,7 +14081,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -17336,14 +14090,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -17353,7 +14104,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -17363,7 +14113,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -17371,12 +14120,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -17384,7 +14131,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -17395,7 +14141,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -17405,18 +14150,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -17425,7 +14167,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -17436,7 +14177,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -17444,12 +14184,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -17459,7 +14197,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -17498,8 +14235,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
- gateway.networking.k8s.io/bundle-version: v1.1.0
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+ gateway.networking.k8s.io/bundle-version: v1.2.1
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: udproutes.gateway.networking.k8s.io
@@ -17559,21 +14296,16 @@ spec:
create a "producer" route for a Service in a different namespace from the
Route.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
ParentRefs must be _distinct_. This means either that:
-
* They select different objects. If this is the case, then parentRef
entries are distinct. In terms of fields, this means that the
multi-part key defined by `group`, `kind`, `namespace`, and `name` must
@@ -17583,10 +14315,8 @@ spec:
optional fields to different values. If one ParentRef sets a
combination of optional fields, all must set the same combination.
-
Some examples:
-
* If one ParentRef sets `sectionName`, all ParentRefs referencing the
same object must also set `sectionName`.
* If one ParentRef sets `port`, all ParentRefs referencing the same
@@ -17594,14 +14324,12 @@ spec:
* If one ParentRef sets `sectionName` and `port`, all ParentRefs
referencing the same object must also set `sectionName` and `port`.
-
It is possible to separately reference multiple distinct objects that may
be collapsed by an implementation. For example, some implementations may
choose to merge compatible Gateway Listeners together. If that is the
case, the list of routes attached to those resources should also be
merged.
-
Note that for ParentRefs that cross namespace boundaries, there are specific
rules. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example,
@@ -17609,12 +14337,10 @@ spec:
generic way to enable other kinds of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -17625,22 +14351,18 @@ spec:
-
items:
description: |-
ParentReference identifies an API object (usually a Gateway) that can be considered
a parent of this resource (usually a route). There are two kinds of parent resources
with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
This API may be extended in the future to support additional kinds of parent
resources.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
properties:
@@ -17652,7 +14374,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -17662,14 +14383,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -17679,7 +14397,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -17689,7 +14406,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -17697,12 +14413,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -17710,7 +14424,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -17721,7 +14434,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -17731,18 +14443,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -17751,7 +14460,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -17762,7 +14470,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -17770,12 +14477,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -17785,7 +14490,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -17820,7 +14524,9 @@ spec:
|| p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port
== p2.port))))
rules:
- description: Rules are a list of UDP matchers and actions.
+ description: |+
+ Rules are a list of UDP matchers and actions.
+
items:
description: UDPRouteRule is the configuration for a given rule.
properties:
@@ -17833,53 +14539,41 @@ spec:
respect weight; if an invalid backend is requested to have 80% of
the packets, then 80% of packets must be dropped instead.
-
Support: Core for Kubernetes Service
-
Support: Extended for Kubernetes ServiceImport
-
Support: Implementation-specific for any other resource
-
Support for weight: Extended
items:
description: |-
BackendRef defines how a Route should forward a request to a Kubernetes
resource.
-
Note that when a namespace different than the local namespace is specified, a
ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
-
When the BackendRef points to a Kubernetes Service, implementations SHOULD
honor the appProtocol field if it is set for the target Service Port.
-
Implementations supporting appProtocol SHOULD recognize the Kubernetes
Standard Application Protocols defined in KEP-3726.
-
If a Service appProtocol isn't specified, an implementation MAY infer the
backend protocol through its own means. Implementations MAY infer the
protocol from the Route type referring to the backend Service.
-
If a Route is not able to send traffic to the backend using the specified
protocol then the backend is considered invalid. Implementations MUST set the
"ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason.
-
-
Note that when the BackendTLSPolicy object is enabled by the implementation,
there are some extra rules about validity to consider here. See the fields
where this struct is used for more information about the exact behavior.
@@ -17898,20 +14592,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -17927,13 +14617,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -17960,13 +14648,11 @@ spec:
implementation supports. Weight is not a percentage and the sum of
weights does not need to equal 100.
-
If only one backend is specified and it has a weight greater than 0, 100%
of the traffic is forwarded to that backend. If weight is set to 0, no
traffic should be forwarded for this entry. If unspecified, weight
defaults to 1.
-
Support for this field varies based on the context where used.
format: int32
maximum: 1000000
@@ -17982,10 +14668,23 @@ spec:
maxItems: 16
minItems: 1
type: array
+ name:
+ description: |-
+ Name is the name of the route rule. This name MUST be unique within a Route if it is set.
+
+ Support: Extended
+ maxLength: 253
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
type: object
maxItems: 16
minItems: 1
type: array
+ x-kubernetes-validations:
+ - message: Rule name must be unique within the route
+ rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)
+ && l1.name == l2.name))
required:
- rules
type: object
@@ -18001,13 +14700,11 @@ spec:
first sees the route and should update the entry as appropriate when the
route or gateway is modified.
-
Note that parent references that cannot be resolved by an implementation
of this API will not be added to this list. Implementations of this API
can only populate Route status for the Gateways/parent resources they are
responsible for.
-
A maximum of 32 Gateways will be represented in this list. An empty list
means the route has not been attached to any Gateway.
items:
@@ -18021,38 +14718,24 @@ spec:
Note that the route's availability is also subject to the Gateway's own
status conditions and listener status.
-
If the Route's ParentRef specifies an existing Gateway that supports
Routes of this kind AND that Gateway's controller has sufficient access,
then that Gateway's controller MUST set the "Accepted" condition on the
Route, to indicate whether the route has been accepted or rejected by the
Gateway, and why.
-
A Route MUST be considered "Accepted" if at least one of the Route's
rules is implemented by the Gateway.
-
There are a number of cases where the "Accepted" condition may not be set
due to lack of controller visibility, that includes when:
-
* The Route refers to a non-existent parent.
* The Route is of a type that the controller does not support.
* The Route is in a namespace the controller does not have access to.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -18094,12 +14777,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -18122,15 +14800,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
@@ -18151,7 +14826,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -18161,14 +14835,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -18178,7 +14849,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -18188,7 +14858,6 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
@@ -18196,12 +14865,10 @@ spec:
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -18209,7 +14876,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -18220,7 +14886,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -18230,18 +14895,15 @@ spec:
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -18250,7 +14912,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -18261,7 +14922,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -18269,12 +14929,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -18284,7 +14942,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml
index 8e83322e140..9dd148bf42b 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.15.0
+ controller-gen.kubebuilder.io/version: v0.16.1
name: backends.gateway.envoyproxy.io
spec:
group: gateway.envoyproxy.io
@@ -93,15 +93,16 @@ spec:
- port
type: object
ip:
- description: IP defines an IP endpoint. Currently, only IPv4
- Addresses are supported.
+ description: IP defines an IP endpoint. Supports both IPv4 and
+ IPv6 addresses.
properties:
address:
- description: Address defines the IP address of the backend
- endpoint.
- maxLength: 15
- minLength: 7
- pattern: ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
+ description: |-
+ Address defines the IP address of the backend endpoint.
+ Supports both IPv4 and IPv6 addresses.
+ maxLength: 45
+ minLength: 3
+ pattern: ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(([0-9a-fA-F]{1,4}:){1,7}[0-9a-fA-F]{1,4}|::|(([0-9a-fA-F]{1,4}:){0,5})?(:[0-9a-fA-F]{1,4}){1,2})$
type: string
port:
description: Port defines the port of the backend endpoint.
@@ -131,12 +132,20 @@ spec:
rule: ((has(self.fqdn) && !(has(self.ip) || has(self.unix))) ||
(has(self.ip) && !(has(self.fqdn) || has(self.unix))) || (has(self.unix)
&& !(has(self.ip) || has(self.fqdn))))
- maxItems: 4
+ maxItems: 64
minItems: 1
type: array
x-kubernetes-validations:
- message: fqdn addresses cannot be mixed with other address types
rule: self.all(f, has(f.fqdn)) || !self.exists(f, has(f.fqdn))
+ fallback:
+ description: |-
+ Fallback indicates whether the backend is designated as a fallback.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
type: object
status:
description: Status defines the current status of Backend.
@@ -144,16 +153,8 @@ spec:
conditions:
description: Conditions describe the current conditions of the Backend.
items:
- description: "Condition contains details for one aspect of the current
- state of this API Resource.\n---\nThis struct is intended for
- direct use as an array at the field path .status.conditions. For
- example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
- observations of a foo's current state.\n\t // Known .status.conditions.type
- are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
- \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
- patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of the current
+ state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -194,12 +195,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
index 20ffe833923..f9fb0f329dd 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.15.0
+ controller-gen.kubebuilder.io/version: v0.16.1
name: backendtrafficpolicies.gateway.envoyproxy.io
spec:
group: gateway.envoyproxy.io
@@ -123,20 +123,48 @@ spec:
description: Connection includes backend connection settings.
properties:
bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
description: |-
BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
If unspecified, an implementation defined default is applied (32768 bytes).
For example, 20Mi, 1Gi, 256Ki etc.
Note: that when the suffix is not provided, the value is interpreted as bytes.
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: BufferLimit must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
type: object
faultInjection:
description: |-
@@ -198,6 +226,18 @@ spec:
active:
description: Active health check configuration
properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
healthyThreshold:
default: 1
description: HealthyThreshold defines the number of healthy
@@ -352,9 +392,11 @@ spec:
- enum:
- HTTP
- TCP
+ - GRPC
- enum:
- HTTP
- TCP
+ - GRPC
description: Type defines the type of health checker.
type: string
unhealthyThreshold:
@@ -374,6 +416,9 @@ spec:
- message: If Health Checker type is TCP, tcp field needs to be
set.
rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)'
+ - message: The grpc field can only be set if the Health Checker
+ type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC'' : true'
passive:
description: Passive passive check configuration
properties:
@@ -421,10 +466,51 @@ spec:
type: boolean
type: object
type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration for backend connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
loadBalancer:
description: |-
LoadBalancer policy to apply when routing traffic from the gateway to
- the backend endpoints
+ the backend endpoints. Defaults to `LeastRequest`.
properties:
consistentHash:
description: |-
@@ -585,11 +671,9 @@ spec:
All individual select conditions must hold True for this rule
and its limit to be applied.
-
If no client selectors are specified, the rule applies to all traffic of
the targeted Route.
-
If the policy targets a Gateway, the rule applies to each Route of the Gateway.
Please note that each Route has its own rate limit counters. For example,
if a Gateway has two Routes, and the policy has a rule with limit 10rps,
@@ -609,6 +693,13 @@ spec:
description: HeaderMatch defines the match attributes
within the HTTP Headers of the request.
properties:
+ invert:
+ default: false
+ description: |-
+ Invert specifies whether the value match result will be inverted.
+ Do not set this field when Type="Distinct", implying matching on any/all unique
+ values within the header.
+ type: boolean
name:
description: Name of the HTTP header.
maxLength: 256
@@ -636,9 +727,6 @@ spec:
type: object
maxItems: 16
type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
sourceCIDR:
description: |-
SourceCIDR is the client IP Address range to match on.
@@ -718,11 +806,9 @@ spec:
All individual select conditions must hold True for this rule
and its limit to be applied.
-
If no client selectors are specified, the rule applies to all traffic of
the targeted Route.
-
If the policy targets a Gateway, the rule applies to each Route of the Gateway.
Please note that each Route has its own rate limit counters. For example,
if a Gateway has two Routes, and the policy has a rule with limit 10rps,
@@ -742,6 +828,13 @@ spec:
description: HeaderMatch defines the match attributes
within the HTTP Headers of the request.
properties:
+ invert:
+ default: false
+ description: |-
+ Invert specifies whether the value match result will be inverted.
+ Do not set this field when Type="Distinct", implying matching on any/all unique
+ values within the header.
+ type: boolean
name:
description: Name of the HTTP header.
maxLength: 256
@@ -769,9 +862,6 @@ spec:
type: object
maxItems: 16
type: array
- x-kubernetes-list-map-keys:
- - name
- x-kubernetes-list-type: map
sourceCIDR:
description: |-
SourceCIDR is the client IP Address range to match on.
@@ -839,6 +929,156 @@ spec:
required:
- type
type: object
+ responseOverride:
+ description: |-
+ ResponseOverride defines the configuration to override specific responses with a custom one.
+ If multiple configurations are specified, the first one to match wins.
+ items:
+ description: ResponseOverride defines the configuration to override
+ specific responses with a custom one.
+ properties:
+ match:
+ description: Match configuration.
+ properties:
+ statusCodes:
+ description: Status code to match on. The match evaluates
+ to true if any of the matches are successful.
+ items:
+ description: StatusCodeMatch defines the configuration
+ for matching a status code.
+ properties:
+ range:
+ description: Range contains the range of status codes.
+ properties:
+ end:
+ description: End of the range, including the end
+ value.
+ type: integer
+ start:
+ description: Start of the range, including the
+ start value.
+ type: integer
+ required:
+ - end
+ - start
+ type: object
+ x-kubernetes-validations:
+ - message: end must be greater than start
+ rule: self.end > self.start
+ type:
+ allOf:
+ - enum:
+ - Value
+ - Range
+ - enum:
+ - Value
+ - Range
+ default: Value
+ description: |-
+ Type is the type of value.
+ Valid values are Value and Range, default is Value.
+ type: string
+ value:
+ description: Value contains the value of the status
+ code.
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: value must be set for type Value
+ rule: '(!has(self.type) || self.type == ''Value'')?
+ has(self.value) : true'
+ - message: range must be set for type Range
+ rule: '(has(self.type) && self.type == ''Range'')? has(self.range)
+ : true'
+ maxItems: 50
+ minItems: 1
+ type: array
+ required:
+ - statusCodes
+ type: object
+ response:
+ description: Response configuration.
+ properties:
+ body:
+ description: Body of the Custom Response
+ properties:
+ inline:
+ description: Inline contains the value as an inline
+ string.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Inline
+ - ValueRef
+ - enum:
+ - Inline
+ - ValueRef
+ default: Inline
+ description: |-
+ Type is the type of method to use to read the body value.
+ Valid values are Inline and ValueRef, default is Inline.
+ type: string
+ valueRef:
+ description: |-
+ ValueRef contains the contents of the body
+ specified as a local object reference.
+ Only a reference to ConfigMap is supported.
+
+ The value of key `response.body` in the ConfigMap will be used as the response body.
+ If the key is not found, the first value in the ConfigMap will be used.
+ properties:
+ group:
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ description: Kind is kind of the referent. For example
+ "HTTPRoute" or "Service".
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ required:
+ - group
+ - kind
+ - name
+ type: object
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: inline must be set for type Inline
+ rule: '(!has(self.type) || self.type == ''Inline'')? has(self.inline)
+ : true'
+ - message: valueRef must be set for type ValueRef
+ rule: '(has(self.type) && self.type == ''ValueRef'')?
+ has(self.valueRef) : true'
+ - message: only ConfigMap is supported for ValueRef
+ rule: 'has(self.valueRef) ? self.valueRef.kind == ''ConfigMap''
+ : true'
+ contentType:
+ description: Content Type of the response. This will be
+ set in the Content-Type header.
+ type: string
+ required:
+ - body
+ type: object
+ required:
+ - match
+ - response
+ type: object
+ type: array
retry:
description: |-
Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
@@ -882,7 +1122,6 @@ spec:
description: |-
RetryOn specifies the retry trigger condition.
-
If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503).
properties:
httpStatusCodes:
@@ -924,7 +1163,6 @@ spec:
This policy and the TargetRef MUST be in the same namespace for this
Policy to have effect
-
Deprecated: use targetRefs/targetSelectors instead
properties:
group:
@@ -949,12 +1187,10 @@ spec:
unspecified, this targetRef targets the entire resource. In the following
resources, SectionName is interpreted as the following:
-
* Gateway: Listener name
* HTTPRoute: HTTPRouteRule name
* Service: Port name
-
If a SectionName is specified, but does not exist on the targeted object,
the Policy must fail to attach, and the policy implementation should record
a `ResolvedRefs` or similar Condition in the Policy's status.
@@ -979,7 +1215,6 @@ spec:
mode works, and a sample Policy resource, refer to the policy attachment
documentation for Gateway API.
-
Note: This should only be used for direct policy attachment when references
to SectionName are actually needed. In all other cases,
LocalPolicyTargetReference should be used.
@@ -1006,12 +1241,10 @@ spec:
unspecified, this targetRef targets the entire resource. In the following
resources, SectionName is interpreted as the following:
-
* Gateway: Listener name
* HTTPRoute: HTTPRouteRule name
* Service: Port name
-
If a SectionName is specified, but does not exist on the targeted object,
the Policy must fail to attach, and the policy implementation should record
a `ResolvedRefs` or similar Condition in the Policy's status.
@@ -1103,6 +1336,11 @@ spec:
Default: unlimited.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
+ requestTimeout:
+ description: RequestTimeout is the time until which entire
+ response is received from the upstream.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
type: object
tcp:
description: Timeout settings for TCP.
@@ -1157,27 +1395,22 @@ spec:
the controller first sees the policy and SHOULD update the entry as
appropriate when the relevant ancestor is modified.
-
Note that choosing the relevant ancestor is left to the Policy designers;
an important part of Policy design is designing the right object level at
which to namespace this status.
-
Note also that implementations MUST ONLY populate ancestor status for
the Ancestor resources they are responsible for. Implementations MUST
use the ControllerName field to uniquely identify the entries in this list
that they are responsible for.
-
Note that to achieve this, the list of PolicyAncestorStatus structs
MUST be treated as a map with a composite key, made up of the AncestorRef
and ControllerName fields combined.
-
A maximum of 16 ancestors will be represented in this list. An empty list
means the Policy is not relevant for any ancestors.
-
If this slice is full, implementations MUST NOT add further entries.
Instead they MUST consider the policy unimplementable and signal that
on any related resources such as the ancestor that would be referenced
@@ -1189,7 +1422,6 @@ spec:
PolicyAncestorStatus describes the status of a route with respect to an
associated Ancestor.
-
Ancestors refer to objects that are either the Target of a policy or above it
in terms of object hierarchy. For example, if a policy targets a Service, the
Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
@@ -1198,28 +1430,23 @@ spec:
SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
have a _very_ good reason otherwise.
-
In the context of policy attachment, the Ancestor is used to distinguish which
resource results in a distinct application of this policy. For example, if a policy
targets a Service, it may have a distinct result per attached Gateway.
-
Policies targeting the same resource may have different effects depending on the
ancestors of those resources. For example, different Gateways targeting the same
Service may have different capabilities, especially if they have different underlying
implementations.
-
For example, in BackendTLSPolicy, the Policy attaches to a Service that is
used as a backend in a HTTPRoute that is itself attached to a Gateway.
In this case, the relevant object for status is the Gateway, and that is the
ancestor object referred to in this status.
-
Note that a parent is also an ancestor, so for objects where the parent is the
relevant object for status, this struct SHOULD still be used.
-
This struct is intended to be used in a slice that's effectively a map,
with a composite key made up of the AncestorRef and the ControllerName.
properties:
@@ -1236,7 +1463,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -1246,14 +1472,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -1263,7 +1486,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -1273,20 +1495,17 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
Gateway has the AllowedRoutes field, and ReferenceGrant provides a
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -1294,7 +1513,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -1305,7 +1523,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -1314,19 +1531,16 @@ spec:
and SectionName are specified, the name and port of the selected listener
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -1335,7 +1549,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -1346,7 +1559,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -1354,12 +1566,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -1369,7 +1579,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -1382,18 +1591,8 @@ spec:
description: Conditions describes the status of the Policy with
respect to the given Ancestor.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -1435,12 +1634,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -1463,15 +1657,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
index 48cfb9f3aad..d3afb65b302 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.15.0
+ controller-gen.kubebuilder.io/version: v0.16.1
name: clienttrafficpolicies.gateway.envoyproxy.io
spec:
group: gateway.envoyproxy.io
@@ -85,11 +85,32 @@ spec:
description: |-
NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP
headers to trust when determining the origin client's IP address.
- Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
- for more details.
+ Only one of NumTrustedHops and TrustedCIDRs must be set.
format: int32
type: integer
+ trustedCIDRs:
+ description: |-
+ TrustedCIDRs is a list of CIDR ranges to trust when evaluating
+ the remote IP address to determine the original client’s IP address.
+ When the remote IP address matches a trusted CIDR and the x-forwarded-for header was sent,
+ each entry in the x-forwarded-for header is evaluated from right to left
+ and the first public non-trusted address is used as the original client address.
+ If all addresses in x-forwarded-for are within the trusted list, the first (leftmost) entry is used.
+ Only one of NumTrustedHops and TrustedCIDRs must be set.
+ items:
+ description: |-
+ CIDR defines a CIDR Address range.
+ A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address range such as "2001:0db8:11a3:09d7::/64".
+ pattern: ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]+))|((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/([0-9]+))
+ type: string
+ minItems: 1
+ type: array
type: object
+ x-kubernetes-validations:
+ - message: only one of numTrustedHops or trustedCIDRs must be
+ set
+ rule: (has(self.numTrustedHops) && !has(self.trustedCIDRs))
+ || (!has(self.numTrustedHops) && has(self.trustedCIDRs))
type: object
x-kubernetes-validations:
- message: customHeader cannot be used in conjunction with xForwardedFor
@@ -98,20 +119,19 @@ spec:
description: Connection includes client connection settings.
properties:
bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
description: |-
BufferLimit provides configuration for the maximum buffer size in bytes for each incoming connection.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
For example, 20Mi, 1Gi, 256Ki etc.
Note that when the suffix is not provided, the value is interpreted as bytes.
Default: 32768 bytes.
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: bufferLimit must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
connectionLimit:
description: ConnectionLimit defines limits related to connections
properties:
@@ -126,11 +146,25 @@ spec:
description: |-
Value of the maximum concurrent connections limit.
When the limit is reached, incoming connections will be closed after the CloseDelay duration.
- Default: unlimited.
format: int64
- minimum: 0
+ minimum: 1
type: integer
+ required:
+ - value
type: object
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each incoming socket.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
type: object
enableProxyProtocol:
description: |-
@@ -147,6 +181,137 @@ spec:
DisableRateLimitHeaders configures Envoy Proxy to omit the "X-RateLimit-" response headers
when rate limiting is enabled.
type: boolean
+ earlyRequestHeaders:
+ description: |-
+ EarlyRequestHeaders defines settings for early request header modification, before envoy performs
+ routing, tracing and built-in header manipulation.
+ properties:
+ add:
+ description: |-
+ Add adds the given header(s) (name, value) to the request
+ before the action. It appends to any existing values associated
+ with the header name.
+
+ Input:
+ GET /foo HTTP/1.1
+ my-header: foo
+
+ Config:
+ add:
+ - name: "my-header"
+ value: "bar,baz"
+
+ Output:
+ GET /foo HTTP/1.1
+ my-header: foo,bar,baz
+ items:
+ description: HTTPHeader represents an HTTP Header name and
+ value as defined by RFC 7230.
+ properties:
+ name:
+ description: |-
+ Name is the name of the HTTP Header to be matched. Name matching MUST be
+ case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
+
+ If multiple entries specify equivalent header names, the first entry with
+ an equivalent name MUST be considered for a match. Subsequent entries
+ with an equivalent header name MUST be ignored. Due to the
+ case-insensitivity of header names, "foo" and "Foo" are considered
+ equivalent.
+ maxLength: 256
+ minLength: 1
+ pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
+ type: string
+ value:
+ description: Value is the value of HTTP Header to be
+ matched.
+ maxLength: 4096
+ minLength: 1
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ maxItems: 16
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ remove:
+ description: |-
+ Remove the given header(s) from the HTTP request before the action. The
+ value of Remove is a list of HTTP header names. Note that the header
+ names are case-insensitive (see
+ https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
+
+ Input:
+ GET /foo HTTP/1.1
+ my-header1: foo
+ my-header2: bar
+ my-header3: baz
+
+ Config:
+ remove: ["my-header1", "my-header3"]
+
+ Output:
+ GET /foo HTTP/1.1
+ my-header2: bar
+ items:
+ type: string
+ maxItems: 16
+ type: array
+ x-kubernetes-list-type: set
+ set:
+ description: |-
+ Set overwrites the request with the given header (name, value)
+ before the action.
+
+ Input:
+ GET /foo HTTP/1.1
+ my-header: foo
+
+ Config:
+ set:
+ - name: "my-header"
+ value: "bar"
+
+ Output:
+ GET /foo HTTP/1.1
+ my-header: bar
+ items:
+ description: HTTPHeader represents an HTTP Header name and
+ value as defined by RFC 7230.
+ properties:
+ name:
+ description: |-
+ Name is the name of the HTTP Header to be matched. Name matching MUST be
+ case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
+
+ If multiple entries specify equivalent header names, the first entry with
+ an equivalent name MUST be considered for a match. Subsequent entries
+ with an equivalent header name MUST be ignored. Due to the
+ case-insensitivity of header names, "foo" and "Foo" are considered
+ equivalent.
+ maxLength: 256
+ minLength: 1
+ pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
+ type: string
+ value:
+ description: Value is the value of HTTP Header to be
+ matched.
+ maxLength: 4096
+ minLength: 1
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ maxItems: 16
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ type: object
enableEnvoyHeaders:
description: |-
EnableEnvoyHeaders configures Envoy Proxy to add the "X-Envoy-" headers to requests
@@ -171,26 +336,21 @@ spec:
description: |-
XForwardedClientCert configures how Envoy Proxy handle the x-forwarded-client-cert (XFCC) HTTP header.
-
x-forwarded-client-cert (XFCC) is an HTTP header used to forward the certificate
information of part or all of the clients or proxies that a request has flowed through,
on its way from the client to the server.
-
Envoy proxy may choose to sanitize/append/forward the XFCC header before proxying the request.
-
If not set, the default behavior is sanitizing the XFCC header.
properties:
certDetailsToAdd:
description: |-
CertDetailsToAdd specifies the fields in the client certificate to be forwarded in the XFCC header.
-
Hash(the SHA 256 digest of the current client certificate) and By(the Subject Alternative Name)
are always included if the client certificate is forwarded.
-
This field is only applicable when the mode is set to `AppendForward` or
`SanitizeSet` and the client connection is mTLS.
items:
@@ -267,31 +427,27 @@ spec:
description: HTTP2 provides HTTP/2 configuration on the listener.
properties:
initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
description: |-
InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
If not set, the default value is 1 MiB.
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: initialConnectionWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
description: |-
InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
If not set, the default value is 64 KiB(64*1024).
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: initialStreamWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
maxConcurrentStreams:
description: |-
MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
@@ -300,6 +456,13 @@ spec:
maximum: 2147483647
minimum: 1
type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
type: object
http3:
description: HTTP3 provides HTTP/3 configuration on the listener.
@@ -332,7 +495,6 @@ spec:
This policy and the TargetRef MUST be in the same namespace for this
Policy to have effect
-
Deprecated: use targetRefs/targetSelectors instead
properties:
group:
@@ -357,12 +519,10 @@ spec:
unspecified, this targetRef targets the entire resource. In the following
resources, SectionName is interpreted as the following:
-
* Gateway: Listener name
* HTTPRoute: HTTPRouteRule name
* Service: Port name
-
If a SectionName is specified, but does not exist on the targeted object,
the Policy must fail to attach, and the policy implementation should record
a `ResolvedRefs` or similar Condition in the Policy's status.
@@ -387,7 +547,6 @@ spec:
mode works, and a sample Policy resource, refer to the policy attachment
documentation for Gateway API.
-
Note: This should only be used for direct policy attachment when references
to SectionName are actually needed. In all other cases,
LocalPolicyTargetReference should be used.
@@ -414,12 +573,10 @@ spec:
unspecified, this targetRef targets the entire resource. In the following
resources, SectionName is interpreted as the following:
-
* Gateway: Listener name
* HTTPRoute: HTTPRouteRule name
* Service: Port name
-
If a SectionName is specified, but does not exist on the targeted object,
the Policy must fail to attach, and the policy implementation should record
a `ResolvedRefs` or similar Condition in the Policy's status.
@@ -532,7 +689,12 @@ spec:
alpnProtocols:
description: |-
ALPNProtocols supplies the list of ALPN protocols that should be
- exposed by the listener. By default h2 and http/1.1 are enabled.
+ exposed by the listener or used by the proxy to connect to the backend.
+ Defaults:
+ 1. HTTPS Routes: h2 and http/1.1 are enabled in listener context.
+ 2. Other Routes: ALPN is disabled.
+ 3. Backends: proxy uses the appropriate ALPN options for the backend protocol.
+ When an empty list is provided, the ALPN TLS extension is disabled.
Supported values are:
- http/1.0
- http/1.1
@@ -575,11 +737,9 @@ spec:
the Certificate Authorities that can be used
as a trust anchor to validate the certificates presented by the client.
-
A single reference to a Kubernetes ConfigMap or a Kubernetes Secret,
with the CA certificate in a key named `ca.crt` is currently supported.
-
References to a resource in different namespace are invalid UNLESS there
is a ReferenceGrant in the target namespace that allows the certificate
to be attached.
@@ -588,11 +748,9 @@ spec:
SecretObjectReference identifies an API object including its namespace,
defaulting to Secret.
-
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
-
References to objects with invalid Group and Kind are not valid, and must
be rejected by the implementation, with appropriate Conditions set
on the containing object.
@@ -623,13 +781,11 @@ spec:
Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -679,6 +835,27 @@ spec:
- "1.2"
- "1.3"
type: string
+ session:
+ description: Session defines settings related to TLS session management.
+ properties:
+ resumption:
+ description: |-
+ Resumption determines the proxy's supported TLS session resumption option.
+ By default, Envoy Gateway does not enable session resumption. Use sessionResumption to
+ enable stateful and stateless session resumption. Users should consider security impacts
+ of different resumption methods. Performance gains from resumption are diminished when
+ Envoy proxy is deployed with more than one replica.
+ properties:
+ stateful:
+ description: Stateful defines setting for stateful (session-id
+ based) session resumption
+ type: object
+ stateless:
+ description: Stateless defines setting for stateless (session-ticket
+ based) session resumption
+ type: object
+ type: object
+ type: object
signatureAlgorithms:
description: |-
SignatureAlgorithms specifies which signature algorithms the listener should
@@ -726,27 +903,22 @@ spec:
the controller first sees the policy and SHOULD update the entry as
appropriate when the relevant ancestor is modified.
-
Note that choosing the relevant ancestor is left to the Policy designers;
an important part of Policy design is designing the right object level at
which to namespace this status.
-
Note also that implementations MUST ONLY populate ancestor status for
the Ancestor resources they are responsible for. Implementations MUST
use the ControllerName field to uniquely identify the entries in this list
that they are responsible for.
-
Note that to achieve this, the list of PolicyAncestorStatus structs
MUST be treated as a map with a composite key, made up of the AncestorRef
and ControllerName fields combined.
-
A maximum of 16 ancestors will be represented in this list. An empty list
means the Policy is not relevant for any ancestors.
-
If this slice is full, implementations MUST NOT add further entries.
Instead they MUST consider the policy unimplementable and signal that
on any related resources such as the ancestor that would be referenced
@@ -758,7 +930,6 @@ spec:
PolicyAncestorStatus describes the status of a route with respect to an
associated Ancestor.
-
Ancestors refer to objects that are either the Target of a policy or above it
in terms of object hierarchy. For example, if a policy targets a Service, the
Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
@@ -767,28 +938,23 @@ spec:
SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
have a _very_ good reason otherwise.
-
In the context of policy attachment, the Ancestor is used to distinguish which
resource results in a distinct application of this policy. For example, if a policy
targets a Service, it may have a distinct result per attached Gateway.
-
Policies targeting the same resource may have different effects depending on the
ancestors of those resources. For example, different Gateways targeting the same
Service may have different capabilities, especially if they have different underlying
implementations.
-
For example, in BackendTLSPolicy, the Policy attaches to a Service that is
used as a backend in a HTTPRoute that is itself attached to a Gateway.
In this case, the relevant object for status is the Gateway, and that is the
ancestor object referred to in this status.
-
Note that a parent is also an ancestor, so for objects where the parent is the
relevant object for status, this struct SHOULD still be used.
-
This struct is intended to be used in a slice that's effectively a map,
with a composite key made up of the AncestorRef and the ControllerName.
properties:
@@ -805,7 +971,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -815,14 +980,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -832,7 +994,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -842,20 +1003,17 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
Gateway has the AllowedRoutes field, and ReferenceGrant provides a
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -863,7 +1021,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -874,7 +1031,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -883,19 +1039,16 @@ spec:
and SectionName are specified, the name and port of the selected listener
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -904,7 +1057,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -915,7 +1067,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -923,12 +1074,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -938,7 +1087,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -951,18 +1099,8 @@ spec:
description: Conditions describes the status of the Policy with
respect to the given Ancestor.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -1004,12 +1142,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -1032,15 +1165,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
index 61827ee1205..0fbbcafe94e 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.15.0
+ controller-gen.kubebuilder.io/version: v0.16.1
name: envoyextensionpolicies.gateway.envoyproxy.io
spec:
group: gateway.envoyproxy.io
@@ -54,13 +54,97 @@ spec:
description: ExtProc defines the configuration for External Processing
filter.
properties:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+ Defaults to "Service" when not specified.
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+ Support: Core (Services with a type other than ExternalName)
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind == ''Service'')
+ ? has(self.port) : true'
backendRefs:
- description: BackendRefs defines the configuration of the external
- processing service
+ description: |-
+ BackendRefs references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
items:
description: BackendRef defines how an ObjectReference that
is specific to BackendRef.
properties:
+ fallback:
+ description: |-
+ Fallback indicates whether the backend is designated as a fallback.
+ Multiple fallback backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -75,20 +159,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -104,13 +184,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -134,15 +212,690 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
- maxItems: 1
- minItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: BackendRefs only supports Service and Backend kind.
- rule: self.all(f, f.kind == 'Service' || f.kind == 'Backend')
- - message: BackendRefs only supports Core and gateway.envoyproxy.io
- group.
- rule: self.all(f, f.group == '' || f.group == 'gateway.envoyproxy.io')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections that
+ Envoy will establish to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel requests
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel retries
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending requests
+ that Envoy will queue to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform active
+ health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines the number
+ of healthy health checks required before a backend
+ host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines a list
+ of HTTP expected responses to match.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of the
+ payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines the http status
+ code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP path that
+ will be requested during health checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time between active
+ health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the expected response
+ payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of the
+ payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ send:
+ description: Send defines the request payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of the
+ payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time to wait for
+ a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines the number
+ of unhealthy health checks required before a backend
+ host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP, http field
+ needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http) : !has(self.http)'
+ - message: If Health Checker type is TCP, tcp field
+ needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)'
+ - message: The grpc field can only be set if the Health
+ Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC'' : true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines the base duration
+ for which a host will be ejected on consecutive
+ failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets the number
+ of consecutive 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors sets the number
+ of consecutive gateway errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time between passive
+ health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets the maximum
+ percentage of hosts in a cluster that can be ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors enables
+ splitting of errors between external and local
+ origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration for backend
+ connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie hash policy
+ when the consistent hash type is set to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes to set for
+ the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header hash policy
+ when the consistent hash type is set to Header.
+ properties:
+ name:
+ description: Name of the header to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent hashing,
+ must be prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header, the header
+ field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie, the cookie
+ field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash, consistentHash
+ field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported for RoundRobin
+ and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash''] ?
+ !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy Protocol when
+ communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ retry:
+ description: |-
+ Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
+ If not set, retry will be disabled.
+ properties:
+ numRetries:
+ default: 2
+ description: NumRetries is the number of retries to
+ be attempted. Defaults to 2.
+ format: int32
+ minimum: 0
+ type: integer
+ perRetry:
+ description: PerRetry is the retry policy to be applied
+ per retry attempt.
+ properties:
+ backOff:
+ description: |-
+ Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
+ back-off algorithm for retries. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries
+ properties:
+ baseInterval:
+ description: BaseInterval is the base interval
+ between retries.
+ format: duration
+ type: string
+ maxInterval:
+ description: |-
+ MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
+ The default is 10 times the base_interval
+ format: duration
+ type: string
+ type: object
+ timeout:
+ description: Timeout is the timeout per retry attempt.
+ format: duration
+ type: string
+ type: object
+ retryOn:
+ description: |-
+ RetryOn specifies the retry trigger condition.
+
+ If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503).
+ properties:
+ httpStatusCodes:
+ description: |-
+ HttpStatusCodes specifies the http status codes to be retried.
+ The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
+ items:
+ description: HTTPStatus defines the http status
+ code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ triggers:
+ description: Triggers specifies the retry trigger
+ condition(Http/Grpc).
+ items:
+ description: TriggerEnum specifies the conditions
+ that trigger retries.
+ enum:
+ - 5xx
+ - gateway-error
+ - reset
+ - connect-failure
+ - retriable-4xx
+ - refused-stream
+ - retriable-status-codes
+ - cancelled
+ - deadline-exceeded
+ - internal
+ - resource-exhausted
+ - unavailable
+ type: string
+ type: array
+ type: object
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ requestTimeout:
+ description: RequestTimeout is the time until which
+ entire response is received from the upstream.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
failOpen:
description: |-
FailOpen defines if requests or responses that cannot be processed due to connectivity to the
@@ -165,6 +918,16 @@ spec:
Defines processing mode for requests. If present, request headers are sent. Request body is processed according
to the specified mode.
properties:
+ attributes:
+ description: |-
+ Defines which attributes are sent to the external processor. Envoy Gateway currently
+ supports only the following attribute prefixes: connection, source, destination,
+ request, response, upstream and xds.route.
+ https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/advanced/attributes
+ items:
+ pattern: ^(connection\.|source\.|destination\.|request\.|response\.|upstream\.|xds\.route_)[a-z_1-9]*$
+ type: string
+ type: array
body:
description: Defines body processing mode
enum:
@@ -178,6 +941,16 @@ spec:
Defines processing mode for responses. If present, response headers are sent. Response body is processed according
to the specified mode.
properties:
+ attributes:
+ description: |-
+ Defines which attributes are sent to the external processor. Envoy Gateway currently
+ supports only the following attribute prefixes: connection, source, destination,
+ request, response, upstream and xds.route.
+ https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/advanced/attributes
+ items:
+ pattern: ^(connection\.|source\.|destination\.|request\.|response\.|upstream\.|xds\.route_)[a-z_1-9]*$
+ type: string
+ type: array
body:
description: Defines body processing mode
enum:
@@ -187,9 +960,17 @@ spec:
type: string
type: object
type: object
- required:
- - backendRefs
type: object
+ x-kubernetes-validations:
+ - message: BackendRefs must be used, backendRef is not supported.
+ rule: '!has(self.backendRef)'
+ - message: BackendRefs only supports Service and Backend kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind
+ == ''Service'' || f.kind == ''Backend'') : true'
+ - message: BackendRefs only supports Core and gateway.envoyproxy.io
+ group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group
+ == "" || f.group == ''gateway.envoyproxy.io'')) : true'
maxItems: 16
type: array
targetRef:
@@ -198,7 +979,6 @@ spec:
This policy and the TargetRef MUST be in the same namespace for this
Policy to have effect
-
Deprecated: use targetRefs/targetSelectors instead
properties:
group:
@@ -223,12 +1003,10 @@ spec:
unspecified, this targetRef targets the entire resource. In the following
resources, SectionName is interpreted as the following:
-
* Gateway: Listener name
* HTTPRoute: HTTPRouteRule name
* Service: Port name
-
If a SectionName is specified, but does not exist on the targeted object,
the Policy must fail to attach, and the policy implementation should record
a `ResolvedRefs` or similar Condition in the Policy's status.
@@ -253,7 +1031,6 @@ spec:
mode works, and a sample Policy resource, refer to the policy attachment
documentation for Gateway API.
-
Note: This should only be used for direct policy attachment when references
to SectionName are actually needed. In all other cases,
LocalPolicyTargetReference should be used.
@@ -280,12 +1057,10 @@ spec:
unspecified, this targetRef targets the entire resource. In the following
resources, SectionName is interpreted as the following:
-
* Gateway: Listener name
* HTTPRoute: HTTPRouteRule name
* Service: Port name
-
If a SectionName is specified, but does not exist on the targeted object,
the Policy must fail to attach, and the policy implementation should record
a `ResolvedRefs` or similar Condition in the Policy's status.
@@ -341,7 +1116,6 @@ spec:
description: |-
Wasm defines a Wasm extension.
-
Note: at the moment, Envoy Gateway does not support configuring Wasm runtime.
v8 is used as the VM runtime for the Wasm extensions.
properties:
@@ -352,14 +1126,12 @@ spec:
description: |-
HTTP is the HTTP URL containing the Wasm code.
-
Note that the HTTP server must be accessible from the Envoy proxy.
properties:
sha256:
description: |-
SHA256 checksum that will be used to verify the Wasm code.
-
If not specified, Envoy Gateway will not verify the downloaded Wasm code.
kubebuilder:validation:Pattern=`^[a-f0-9]{64}$`
type: string
@@ -374,7 +1146,6 @@ spec:
description: |-
Image is the OCI image containing the Wasm code.
-
Note that the image must be accessible from the Envoy Gateway.
properties:
pullSecretRef:
@@ -408,13 +1179,11 @@ spec:
Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -430,10 +1199,8 @@ spec:
description: |-
SHA256 checksum that will be used to verify the OCI image.
-
It must match the digest of the OCI image.
-
If not specified, Envoy Gateway will not verify the downloaded OCI image.
kubebuilder:validation:Pattern=`^[a-f0-9]{64}$`
type: string
@@ -450,10 +1217,8 @@ spec:
PullPolicy is the policy to use when pulling the Wasm module by either the HTTP or Image source.
This field is only applicable when the SHA256 field is not set.
-
If not specified, the default policy is IfNotPresent except for OCI images whose tag is latest.
-
Note: EG does not update the Wasm module every time an Envoy proxy requests
the Wasm module even if the pull policy is set to Always.
It only updates the Wasm module when the EnvoyExtension resource version changes.
@@ -487,6 +1252,17 @@ spec:
Config is the configuration for the Wasm extension.
This configuration will be passed as a JSON string to the Wasm extension.
x-kubernetes-preserve-unknown-fields: true
+ env:
+ description: Env configures the environment for the Wasm extension
+ properties:
+ hostKeys:
+ description: |-
+ HostKeys is a list of keys for environment variables from the host envoy process
+ that should be passed into the Wasm VM. This is useful for passing secrets to to Wasm extensions.
+ items:
+ type: string
+ type: array
+ type: object
failOpen:
default: false
description: |-
@@ -510,7 +1286,6 @@ spec:
RootContext and Contexts if applicable (e.g., an Wasm HttpFilter and an Wasm AccessLog).
If left blank, all extensions with a blank root_id with the same vm_id will share Context(s).
-
Note: RootID must match the root_id parameter used to register the Context in the Wasm code.
type: string
required:
@@ -554,27 +1329,22 @@ spec:
the controller first sees the policy and SHOULD update the entry as
appropriate when the relevant ancestor is modified.
-
Note that choosing the relevant ancestor is left to the Policy designers;
an important part of Policy design is designing the right object level at
which to namespace this status.
-
Note also that implementations MUST ONLY populate ancestor status for
the Ancestor resources they are responsible for. Implementations MUST
use the ControllerName field to uniquely identify the entries in this list
that they are responsible for.
-
Note that to achieve this, the list of PolicyAncestorStatus structs
MUST be treated as a map with a composite key, made up of the AncestorRef
and ControllerName fields combined.
-
A maximum of 16 ancestors will be represented in this list. An empty list
means the Policy is not relevant for any ancestors.
-
If this slice is full, implementations MUST NOT add further entries.
Instead they MUST consider the policy unimplementable and signal that
on any related resources such as the ancestor that would be referenced
@@ -586,7 +1356,6 @@ spec:
PolicyAncestorStatus describes the status of a route with respect to an
associated Ancestor.
-
Ancestors refer to objects that are either the Target of a policy or above it
in terms of object hierarchy. For example, if a policy targets a Service, the
Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
@@ -595,28 +1364,23 @@ spec:
SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
have a _very_ good reason otherwise.
-
In the context of policy attachment, the Ancestor is used to distinguish which
resource results in a distinct application of this policy. For example, if a policy
targets a Service, it may have a distinct result per attached Gateway.
-
Policies targeting the same resource may have different effects depending on the
ancestors of those resources. For example, different Gateways targeting the same
Service may have different capabilities, especially if they have different underlying
implementations.
-
For example, in BackendTLSPolicy, the Policy attaches to a Service that is
used as a backend in a HTTPRoute that is itself attached to a Gateway.
In this case, the relevant object for status is the Gateway, and that is the
ancestor object referred to in this status.
-
Note that a parent is also an ancestor, so for objects where the parent is the
relevant object for status, this struct SHOULD still be used.
-
This struct is intended to be used in a slice that's effectively a map,
with a composite key made up of the AncestorRef and the ControllerName.
properties:
@@ -633,7 +1397,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -643,14 +1406,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -660,7 +1420,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -670,20 +1429,17 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
Gateway has the AllowedRoutes field, and ReferenceGrant provides a
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -691,7 +1447,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -702,7 +1457,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -711,19 +1465,16 @@ spec:
and SectionName are specified, the name and port of the selected listener
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -732,7 +1483,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -743,7 +1493,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -751,12 +1500,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -766,7 +1513,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -779,18 +1525,8 @@ spec:
description: Conditions describes the status of the Policy with
respect to the given Ancestor.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -832,12 +1568,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -860,15 +1591,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml
index e385b0d4bb0..591e61a4e53 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.15.0
+ controller-gen.kubebuilder.io/version: v0.16.1
name: envoypatchpolicies.gateway.envoyproxy.io
spec:
group: gateway.envoyproxy.io
@@ -71,6 +71,15 @@ spec:
for move or copy operations
Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
type: string
+ jsonPath:
+ description: |-
+ JSONPath is a JSONPath expression. Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details.
+ It produces one or more JSONPointer expressions based on the given JSON document.
+ If no JSONPointer is found, it will result in an error.
+ If the 'Path' property is also set, it will be appended to the resulting JSONPointer expressions from the JSONPath evaluation.
+ This is useful when creating a property that does not yet exist in the JSON document.
+ The final JSONPointer expressions specifies the locations in the target document/field where the operation will be applied.
+ type: string
op:
description: Op is the type of operation to perform
enum:
@@ -83,8 +92,8 @@ spec:
type: string
path:
description: |-
- Path is the location of the target document/field where the operation will be performed
- Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
+ Path is a JSONPointer expression. Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
+ It specifies the location of the target document/field where the operation will be performed
type: string
value:
description: |-
@@ -93,7 +102,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
required:
- op
- - path
type: object
type:
description: Type is the typed URL of the Envoy xDS Resource
@@ -174,27 +182,22 @@ spec:
the controller first sees the policy and SHOULD update the entry as
appropriate when the relevant ancestor is modified.
-
Note that choosing the relevant ancestor is left to the Policy designers;
an important part of Policy design is designing the right object level at
which to namespace this status.
-
Note also that implementations MUST ONLY populate ancestor status for
the Ancestor resources they are responsible for. Implementations MUST
use the ControllerName field to uniquely identify the entries in this list
that they are responsible for.
-
Note that to achieve this, the list of PolicyAncestorStatus structs
MUST be treated as a map with a composite key, made up of the AncestorRef
and ControllerName fields combined.
-
A maximum of 16 ancestors will be represented in this list. An empty list
means the Policy is not relevant for any ancestors.
-
If this slice is full, implementations MUST NOT add further entries.
Instead they MUST consider the policy unimplementable and signal that
on any related resources such as the ancestor that would be referenced
@@ -206,7 +209,6 @@ spec:
PolicyAncestorStatus describes the status of a route with respect to an
associated Ancestor.
-
Ancestors refer to objects that are either the Target of a policy or above it
in terms of object hierarchy. For example, if a policy targets a Service, the
Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
@@ -215,28 +217,23 @@ spec:
SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
have a _very_ good reason otherwise.
-
In the context of policy attachment, the Ancestor is used to distinguish which
resource results in a distinct application of this policy. For example, if a policy
targets a Service, it may have a distinct result per attached Gateway.
-
Policies targeting the same resource may have different effects depending on the
ancestors of those resources. For example, different Gateways targeting the same
Service may have different capabilities, especially if they have different underlying
implementations.
-
For example, in BackendTLSPolicy, the Policy attaches to a Service that is
used as a backend in a HTTPRoute that is itself attached to a Gateway.
In this case, the relevant object for status is the Gateway, and that is the
ancestor object referred to in this status.
-
Note that a parent is also an ancestor, so for objects where the parent is the
relevant object for status, this struct SHOULD still be used.
-
This struct is intended to be used in a slice that's effectively a map,
with a composite key made up of the AncestorRef and the ControllerName.
properties:
@@ -253,7 +250,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -263,14 +259,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -280,7 +273,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -290,20 +282,17 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
Gateway has the AllowedRoutes field, and ReferenceGrant provides a
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -311,7 +300,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -322,7 +310,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -331,19 +318,16 @@ spec:
and SectionName are specified, the name and port of the selected listener
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -352,7 +336,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -363,7 +346,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -371,12 +353,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -386,7 +366,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -399,18 +378,8 @@ spec:
description: Conditions describes the status of the Policy with
respect to the given Ancestor.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -452,12 +421,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -480,15 +444,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
index 74438fea24c..5ee955e8f65 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.15.0
+ controller-gen.kubebuilder.io/version: v0.16.1
name: envoyproxies.gateway.envoyproxy.io
spec:
group: gateway.envoyproxy.io
@@ -51,7 +51,12 @@ spec:
alpnProtocols:
description: |-
ALPNProtocols supplies the list of ALPN protocols that should be
- exposed by the listener. By default h2 and http/1.1 are enabled.
+ exposed by the listener or used by the proxy to connect to the backend.
+ Defaults:
+ 1. HTTPS Routes: h2 and http/1.1 are enabled in listener context.
+ 2. Other Routes: ALPN is disabled.
+ 3. Backends: proxy uses the appropriate ALPN options for the backend protocol.
+ When an empty list is provided, the ALPN TLS extension is disabled.
Supported values are:
- http/1.0
- http/1.1
@@ -114,13 +119,11 @@ spec:
Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -193,21 +196,73 @@ spec:
We strongly recommend using `egctl x translate` to generate a `EnvoyProxy` resource with the `Bootstrap` field set to the default
Bootstrap configuration used. You can edit this configuration, and rerun `egctl x translate` to ensure there are no validation errors.
properties:
+ jsonPatches:
+ description: |-
+ JSONPatches is an array of JSONPatches to be applied to the default bootstrap. Patches are
+ applied in the order in which they are defined.
+ items:
+ description: |-
+ JSONPatchOperation defines the JSON Patch Operation as defined in
+ https://datatracker.ietf.org/doc/html/rfc6902
+ properties:
+ from:
+ description: |-
+ From is the source location of the value to be copied or moved. Only valid
+ for move or copy operations
+ Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
+ type: string
+ jsonPath:
+ description: |-
+ JSONPath is a JSONPath expression. Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details.
+ It produces one or more JSONPointer expressions based on the given JSON document.
+ If no JSONPointer is found, it will result in an error.
+ If the 'Path' property is also set, it will be appended to the resulting JSONPointer expressions from the JSONPath evaluation.
+ This is useful when creating a property that does not yet exist in the JSON document.
+ The final JSONPointer expressions specifies the locations in the target document/field where the operation will be applied.
+ type: string
+ op:
+ description: Op is the type of operation to perform
+ enum:
+ - add
+ - remove
+ - replace
+ - move
+ - copy
+ - test
+ type: string
+ path:
+ description: |-
+ Path is a JSONPointer expression. Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
+ It specifies the location of the target document/field where the operation will be performed
+ type: string
+ value:
+ description: |-
+ Value is the new value of the path location. The value is only used by
+ the `add` and `replace` operations.
+ x-kubernetes-preserve-unknown-fields: true
+ required:
+ - op
+ type: object
+ type: array
type:
default: Replace
description: |-
- Type is the type of the bootstrap configuration, it should be either Replace or Merge.
+ Type is the type of the bootstrap configuration, it should be either Replace, Merge, or JSONPatch.
If unspecified, it defaults to Replace.
enum:
- Merge
- Replace
+ - JSONPatch
type: string
value:
description: Value is a YAML string of the bootstrap.
type: string
- required:
- - value
type: object
+ x-kubernetes-validations:
+ - message: provided bootstrap patch doesn't match the configured patch
+ type
+ rule: 'self.type == ''JSONPatch'' ? self.jsonPatches.size() > 0
+ : has(self.value)'
concurrency:
description: |-
Concurrency defines the number of worker threads to run. If unset, it defaults to
@@ -229,46 +284,36 @@ spec:
If unspecified, the default filter order is applied.
Default filter order is:
-
- envoy.filters.http.health_check
-
- envoy.filters.http.fault
-
- envoy.filters.http.cors
-
- envoy.filters.http.ext_authz
-
- envoy.filters.http.basic_auth
-
- envoy.filters.http.oauth2
-
- envoy.filters.http.jwt_authn
+ - envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
-
- envoy.filters.http.wasm
-
- envoy.filters.http.rbac
-
- envoy.filters.http.local_ratelimit
-
- envoy.filters.http.ratelimit
+ - envoy.filters.http.custom_response
- envoy.filters.http.router
-
Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain.
items:
description: FilterPosition defines the position of an Envoy HTTP
@@ -286,11 +331,13 @@ spec:
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
+ - envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
+ - envoy.filters.http.custom_response
type: string
before:
description: |-
@@ -304,11 +351,13 @@ spec:
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
+ - envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
+ - envoy.filters.http.custom_response
type: string
name:
description: Name of the filter.
@@ -320,11 +369,13 @@ spec:
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
+ - envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
+ - envoy.filters.http.custom_response
type: string
required:
- name
@@ -336,6 +387,20 @@ spec:
rule: (has(self.before) && !has(self.after)) || (!has(self.before)
&& has(self.after))
type: array
+ ipFamily:
+ description: |-
+ IPFamily specifies the IP family for the EnvoyProxy fleet.
+ This setting only affects the Gateway listener port and does not impact
+ other aspects of the Envoy proxy configuration.
+ If not specified, the system will operate as follows:
+ - It defaults to IPv4 only.
+ - IPv6 and dual-stack environments are not supported in this default configuration.
+ Note: To enable IPv6 or dual-stack functionality, explicit configuration is required.
+ enum:
+ - IPv4
+ - IPv6
+ - DualStack
+ type: string
logging:
default:
level:
@@ -428,9 +493,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap
@@ -500,9 +563,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret
@@ -531,11 +592,9 @@ spec:
Claims lists the names of resources, defined in spec.resourceClaims,
that are used by this container.
-
This is an alpha field and requires enabling the
DynamicResourceAllocation feature gate.
-
This field is immutable. It can only be set for containers.
items:
description: ResourceClaim references one entry
@@ -547,6 +606,12 @@ spec:
the Pod where this field is used. It makes that resource available
inside a container.
type: string
+ request:
+ description: |-
+ Request is the name chosen for a request in the referenced claim.
+ If empty, everything from the claim is made available, otherwise
+ only the result of this request.
+ type: string
required:
- name
type: object
@@ -652,7 +717,7 @@ spec:
procMount:
description: |-
procMount denotes the type of proc mount to use for the containers.
- The default is DefaultProcMount which uses the container runtime defaults for
+ The default value is Default which uses the container runtime defaults for
readonly paths and masked paths.
This requires the ProcMountType feature flag to be enabled.
Note that this field cannot be set when spec.os.name is windows.
@@ -734,7 +799,6 @@ spec:
type indicates which kind of seccomp profile will be applied.
Valid options are:
-
Localhost - a profile defined in a file on the node should be used.
RuntimeDefault - the container runtime default profile should be used.
Unconfined - no profile should be applied.
@@ -810,10 +874,8 @@ spec:
RecursiveReadOnly specifies whether read-only mounts should be handled
recursively.
-
If ReadOnly is false, this field has no meaning and must be unspecified.
-
If ReadOnly is true, and this field is set to Disabled, the mount is not made
recursively read-only. If this field is set to IfPossible, the mount is made
recursively read-only, if it is supported by the container runtime. If this
@@ -821,11 +883,9 @@ spec:
supported by the container runtime, otherwise the pod will not be started and
an error will be generated to indicate the reason.
-
If this field is set to IfPossible or Enabled, MountPropagation must be set to
None (or be unspecified, which defaults to None).
-
If this field is not specified, it is treated as an equivalent of Disabled.
type: string
subPath:
@@ -859,7 +919,6 @@ spec:
description: |-
Type is the type of merge operation to perform
-
By default, StrategicMerge is used as the patch type.
type: string
value:
@@ -1167,7 +1226,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -1182,7 +1241,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -1352,7 +1411,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -1367,7 +1426,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -1536,7 +1595,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -1551,7 +1610,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -1721,7 +1780,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -1736,7 +1795,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -1844,9 +1903,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -1900,12 +1957,10 @@ spec:
Some volume types allow the Kubelet to change the ownership of that volume
to be owned by the pod:
-
1. The owning GID will be the FSGroup
2. The setgid bit is set (new files created in the volume will be owned by FSGroup)
3. The permission bits are OR'd with rw-rw----
-
If unset, the Kubelet will not modify the ownership and permissions of any volume.
Note that this field cannot be set when spec.os.name is windows.
format: int64
@@ -1949,6 +2004,32 @@ spec:
Note that this field cannot be set when spec.os.name is windows.
format: int64
type: integer
+ seLinuxChangePolicy:
+ description: |-
+ seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod.
+ It has no effect on nodes that do not support SELinux or to volumes does not support SELinux.
+ Valid values are "MountOption" and "Recursive".
+
+ "Recursive" means relabeling of all files on all Pod volumes by the container runtime.
+ This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.
+
+ "MountOption" mounts all eligible Pod volumes with `-o context` mount option.
+ This requires all Pods that share the same volume to use the same SELinux label.
+ It is not possible to share the same volume among privileged and unprivileged Pods.
+ Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes
+ whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their
+ CSIDriver instance. Other volumes are always re-labelled recursively.
+ "MountOption" value is allowed only when SELinuxMount feature gate is enabled.
+
+ If not specified and SELinuxMount feature gate is enabled, "MountOption" is used.
+ If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes
+ and "Recursive" for all other volumes.
+
+ This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.
+
+ All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state.
+ Note that this field cannot be set when spec.os.name is windows.
+ type: string
seLinuxOptions:
description: |-
The SELinux context to be applied to all containers.
@@ -1992,7 +2073,6 @@ spec:
type indicates which kind of seccomp profile will be applied.
Valid options are:
-
Localhost - a profile defined in a file on the node should be used.
RuntimeDefault - the container runtime default profile should be used.
Unconfined - no profile should be applied.
@@ -2002,18 +2082,28 @@ spec:
type: object
supplementalGroups:
description: |-
- A list of groups applied to the first process run in each container, in addition
- to the container's primary GID, the fsGroup (if specified), and group memberships
- defined in the container image for the uid of the container process. If unspecified,
- no additional groups are added to any container. Note that group memberships
- defined in the container image for the uid of the container process are still effective,
- even if they are not included in this list.
+ A list of groups applied to the first process run in each container, in
+ addition to the container's primary GID and fsGroup (if specified). If
+ the SupplementalGroupsPolicy feature is enabled, the
+ supplementalGroupsPolicy field determines whether these are in addition
+ to or instead of any group memberships defined in the container image.
+ If unspecified, no additional groups are added, though group memberships
+ defined in the container image may still be used, depending on the
+ supplementalGroupsPolicy field.
Note that this field cannot be set when spec.os.name is windows.
items:
format: int64
type: integer
type: array
x-kubernetes-list-type: atomic
+ supplementalGroupsPolicy:
+ description: |-
+ Defines how supplemental groups of the first container processes are calculated.
+ Valid values are "Merge" and "Strict". If not specified, "Merge" is used.
+ (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled
+ and the container runtime must implement support for this feature.
+ Note that this field cannot be set when spec.os.name is windows.
+ type: string
sysctls:
description: |-
Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported
@@ -2177,7 +2267,6 @@ spec:
Keys that don't exist in the incoming pod labels will
be ignored. A null or empty list means only match against labelSelector.
-
This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default).
items:
type: string
@@ -2217,7 +2306,6 @@ spec:
Valid values are integers greater than 0.
When value is not nil, WhenUnsatisfiable must be DoNotSchedule.
-
For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same
labelSelector spread as 2/2/2:
| zone1 | zone2 | zone3 |
@@ -2235,7 +2323,6 @@ spec:
- Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations.
- Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.
-
If this value is nil, the behavior is equivalent to the Honor policy.
This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
type: string
@@ -2247,7 +2334,6 @@ spec:
has a toleration, are included.
- Ignore: node taints are ignored. All nodes are included.
-
If this value is nil, the behavior is equivalent to the Ignore policy.
This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
type: string
@@ -2304,6 +2390,8 @@ spec:
description: |-
awsElasticBlockStore represents an AWS Disk resource that is attached to a
kubelet's host machine and then exposed to the pod.
+ Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree
+ awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver.
More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
properties:
fsType:
@@ -2312,7 +2400,6 @@ spec:
Tip: Ensure that the filesystem type is supported by the host operating system.
Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
- TODO: how do we prevent errors in the filesystem from compromising the machine
type: string
partition:
description: |-
@@ -2336,9 +2423,10 @@ spec:
- volumeID
type: object
azureDisk:
- description: azureDisk represents an Azure Data
- Disk mount on the host and bind mount to the
- pod.
+ description: |-
+ azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
+ Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type
+ are redirected to the disk.csi.azure.com CSI driver.
properties:
cachingMode:
description: 'cachingMode is the Host Caching
@@ -2353,6 +2441,7 @@ spec:
disk in the blob storage
type: string
fsType:
+ default: ext4
description: |-
fsType is Filesystem type to mount.
Must be a filesystem type supported by the host operating system.
@@ -2366,6 +2455,7 @@ spec:
availability set). defaults to shared'
type: string
readOnly:
+ default: false
description: |-
readOnly Defaults to false (read/write). ReadOnly here will force
the ReadOnly setting in VolumeMounts.
@@ -2375,9 +2465,10 @@ spec:
- diskURI
type: object
azureFile:
- description: azureFile represents an Azure File
- Service mount on the host and bind mount to
- the pod.
+ description: |-
+ azureFile represents an Azure File Service mount on the host and bind mount to the pod.
+ Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type
+ are redirected to the file.csi.azure.com CSI driver.
properties:
readOnly:
description: |-
@@ -2398,8 +2489,9 @@ spec:
- shareName
type: object
cephfs:
- description: cephFS represents a Ceph FS mount
- on the host that shares a pod's lifetime
+ description: |-
+ cephFS represents a Ceph FS mount on the host that shares a pod's lifetime.
+ Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported.
properties:
monitors:
description: |-
@@ -2437,9 +2529,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2454,6 +2544,8 @@ spec:
cinder:
description: |-
cinder represents a cinder volume attached and mounted on kubelets host machine.
+ Deprecated: Cinder is deprecated. All operations for the in-tree cinder type
+ are redirected to the cinder.csi.openstack.org CSI driver.
More info: https://examples.k8s.io/mysql-cinder-pd/README.md
properties:
fsType:
@@ -2481,9 +2573,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2556,9 +2646,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the
@@ -2569,7 +2657,7 @@ spec:
csi:
description: csi (Container Storage Interface)
represents ephemeral storage that is handled
- by certain external CSI drivers (Beta feature).
+ by certain external CSI drivers.
properties:
driver:
description: |-
@@ -2597,9 +2685,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -2747,7 +2833,6 @@ spec:
The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts,
and deleted when the pod is removed.
-
Use this if:
a) the volume is only needed while the pod runs,
b) features of normal volumes like restoring from snapshot or capacity
@@ -2758,17 +2843,14 @@ spec:
information on the connection between this volume type
and PersistentVolumeClaim).
-
Use PersistentVolumeClaim or one of the vendor-specific
APIs for volumes that persist for longer than the lifecycle
of an individual pod.
-
Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to
be used that way - see the documentation of the driver for
more information.
-
A pod can use both types of ephemeral volumes and
persistent volumes at the same time.
properties:
@@ -2782,7 +2864,6 @@ spec:
entry. Pod validation will reject the pod if the concatenated name
is not valid for a PVC (for example, too long).
-
An existing PVC with that name that is not owned by the pod
will *not* be used for the pod to avoid using an unrelated
volume by mistake. Starting the pod is then blocked until
@@ -2792,11 +2873,9 @@ spec:
this should not be necessary, but it may be useful when
manually reconstructing a broken cluster.
-
This field is read-only and no changes will be made by Kubernetes
to the PVC after it has been created.
-
Required, must not be nil.
properties:
metadata:
@@ -3002,7 +3081,7 @@ spec:
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
- (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).
type: string
volumeMode:
description: |-
@@ -3029,7 +3108,6 @@ spec:
fsType is the filesystem type to mount.
Must be a filesystem type supported by the host operating system.
Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
- TODO: how do we prevent errors in the filesystem from compromising the machine
type: string
lun:
description: 'lun is Optional: FC target
@@ -3061,6 +3139,7 @@ spec:
description: |-
flexVolume represents a generic volume resource that is
provisioned/attached using an exec based plugin.
+ Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead.
properties:
driver:
description: driver is the name of the driver
@@ -3098,9 +3177,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3108,10 +3185,9 @@ spec:
- driver
type: object
flocker:
- description: flocker represents a Flocker volume
- attached to a kubelet's host machine. This
- depends on the Flocker control service being
- running
+ description: |-
+ flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running.
+ Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported.
properties:
datasetName:
description: |-
@@ -3128,6 +3204,8 @@ spec:
description: |-
gcePersistentDisk represents a GCE Disk resource that is attached to a
kubelet's host machine and then exposed to the pod.
+ Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree
+ gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver.
More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
properties:
fsType:
@@ -3136,7 +3214,6 @@ spec:
Tip: Ensure that the filesystem type is supported by the host operating system.
Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
- TODO: how do we prevent errors in the filesystem from compromising the machine
type: string
partition:
description: |-
@@ -3164,7 +3241,7 @@ spec:
gitRepo:
description: |-
gitRepo represents a git repository at a particular revision.
- DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an
+ Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an
EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir
into the Pod's container.
properties:
@@ -3188,6 +3265,7 @@ spec:
glusterfs:
description: |-
glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.
+ Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported.
More info: https://examples.k8s.io/volumes/glusterfs/README.md
properties:
endpoints:
@@ -3217,9 +3295,6 @@ spec:
used for system agents or other privileged things that are allowed
to see the host machine. Most containers will NOT need this.
More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath
- ---
- TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not
- mount host directories as read/write.
properties:
path:
description: |-
@@ -3236,6 +3311,41 @@ spec:
required:
- path
type: object
+ image:
+ description: |-
+ image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine.
+ The volume is resolved at pod startup depending on which PullPolicy value is provided:
+
+ - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.
+ - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.
+ - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.
+
+ The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation.
+ A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message.
+ The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field.
+ The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images.
+ The volume will be mounted read-only (ro) and non-executable files (noexec).
+ Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath).
+ The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.
+ properties:
+ pullPolicy:
+ description: |-
+ Policy for pulling OCI objects. Possible values are:
+ Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.
+ Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.
+ IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.
+ Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.
+ type: string
+ reference:
+ description: |-
+ Required: Image or artifact reference to be used.
+ Behaves in the same way as pod.spec.containers[*].image.
+ Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets.
+ More info: https://kubernetes.io/docs/concepts/containers/images
+ This field is optional to allow higher level config management to default or override
+ container images in workload controllers like Deployments and StatefulSets.
+ type: string
+ type: object
iscsi:
description: |-
iscsi represents an ISCSI Disk resource that is attached to a
@@ -3256,7 +3366,6 @@ spec:
Tip: Ensure that the filesystem type is supported by the host operating system.
Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi
- TODO: how do we prevent errors in the filesystem from compromising the machine
type: string
initiatorName:
description: |-
@@ -3269,6 +3378,7 @@ spec:
Name.
type: string
iscsiInterface:
+ default: default
description: |-
iscsiInterface is the interface Name that uses an iSCSI transport.
Defaults to 'default' (tcp).
@@ -3302,9 +3412,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3369,9 +3477,9 @@ spec:
- claimName
type: object
photonPersistentDisk:
- description: photonPersistentDisk represents
- a PhotonController persistent disk attached
- and mounted on kubelets host machine
+ description: |-
+ photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine.
+ Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported.
properties:
fsType:
description: |-
@@ -3387,9 +3495,11 @@ spec:
- pdID
type: object
portworxVolume:
- description: portworxVolume represents a portworx
- volume attached and mounted on kubelets host
- machine
+ description: |-
+ portworxVolume represents a portworx volume attached and mounted on kubelets host machine.
+ Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type
+ are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate
+ is on.
properties:
fsType:
description: |-
@@ -3425,25 +3535,24 @@ spec:
format: int32
type: integer
sources:
- description: sources is the list of volume
- projections
+ description: |-
+ sources is the list of volume projections. Each entry in this list
+ handles one source.
items:
- description: Projection that may be projected
- along with other supported volume types
+ description: |-
+ Projection that may be projected along with other supported volume types.
+ Exactly one of these fields must be set.
properties:
clusterTrustBundle:
description: |-
ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field
of ClusterTrustBundle objects in an auto-updating file.
-
Alpha, gated by the ClusterTrustBundleProjection feature gate.
-
ClusterTrustBundle objects can either be selected by name, or by the
combination of signer name and a label selector.
-
Kubelet performs aggressive normalization of the PEM contents written
into the pod filesystem. Esoteric PEM features such as inter-block
comments and block headers are stripped. Certificates are deduplicated.
@@ -3582,9 +3691,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify
@@ -3738,9 +3845,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify
@@ -3784,8 +3889,9 @@ spec:
x-kubernetes-list-type: atomic
type: object
quobyte:
- description: quobyte represents a Quobyte mount
- on the host that shares a pod's lifetime
+ description: |-
+ quobyte represents a Quobyte mount on the host that shares a pod's lifetime.
+ Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported.
properties:
group:
description: |-
@@ -3824,6 +3930,7 @@ spec:
rbd:
description: |-
rbd represents a Rados Block Device mount on the host that shares a pod's lifetime.
+ Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported.
More info: https://examples.k8s.io/volumes/rbd/README.md
properties:
fsType:
@@ -3832,7 +3939,6 @@ spec:
Tip: Ensure that the filesystem type is supported by the host operating system.
Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd
- TODO: how do we prevent errors in the filesystem from compromising the machine
type: string
image:
description: |-
@@ -3840,6 +3946,7 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
type: string
keyring:
+ default: /etc/ceph/keyring
description: |-
keyring is the path to key ring for RBDUser.
Default is /etc/ceph/keyring.
@@ -3854,6 +3961,7 @@ spec:
type: array
x-kubernetes-list-type: atomic
pool:
+ default: rbd
description: |-
pool is the rados pool name.
Default is rbd.
@@ -3879,13 +3987,12 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
user:
+ default: admin
description: |-
user is the rados user name.
Default is admin.
@@ -3896,11 +4003,12 @@ spec:
- monitors
type: object
scaleIO:
- description: scaleIO represents a ScaleIO persistent
- volume attached and mounted on Kubernetes
- nodes.
+ description: |-
+ scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.
+ Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported.
properties:
fsType:
+ default: xfs
description: |-
fsType is the filesystem type to mount.
Must be a filesystem type supported by the host operating system.
@@ -3933,9 +4041,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -3945,6 +4051,7 @@ spec:
false
type: boolean
storageMode:
+ default: ThinProvisioned
description: |-
storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.
Default is ThinProvisioned.
@@ -4034,9 +4141,9 @@ spec:
type: string
type: object
storageos:
- description: storageOS represents a StorageOS
- volume attached and mounted on Kubernetes
- nodes.
+ description: |-
+ storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.
+ Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported.
properties:
fsType:
description: |-
@@ -4061,9 +4168,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -4083,9 +4188,10 @@ spec:
type: string
type: object
vsphereVolume:
- description: vsphereVolume represents a vSphere
- volume attached and mounted on kubelets host
- machine
+ description: |-
+ vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine.
+ Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type
+ are redirected to the csi.vsphere.vmware.com CSI driver.
properties:
fsType:
description: |-
@@ -4120,12 +4226,8 @@ spec:
existing pods with new ones.
properties:
rollingUpdate:
- description: |-
- Rolling update config params. Present only if type = "RollingUpdate".
- ---
- TODO: Update this to follow our convention for oneOf, whatever we decide it
- to be. Same as Deployment `strategy.rollingUpdate`.
- See https://github.com/kubernetes/kubernetes/issues/35345
+ description: Rolling update config params. Present
+ only if type = "RollingUpdate".
properties:
maxSurge:
anyOf:
@@ -4228,9 +4330,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap
@@ -4300,9 +4400,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret
@@ -4331,11 +4429,9 @@ spec:
Claims lists the names of resources, defined in spec.resourceClaims,
that are used by this container.
-
This is an alpha field and requires enabling the
DynamicResourceAllocation feature gate.
-
This field is immutable. It can only be set for containers.
items:
description: ResourceClaim references one entry
@@ -4347,6 +4443,12 @@ spec:
the Pod where this field is used. It makes that resource available
inside a container.
type: string
+ request:
+ description: |-
+ Request is the name chosen for a request in the referenced claim.
+ If empty, everything from the claim is made available, otherwise
+ only the result of this request.
+ type: string
required:
- name
type: object
@@ -4452,7 +4554,7 @@ spec:
procMount:
description: |-
procMount denotes the type of proc mount to use for the containers.
- The default is DefaultProcMount which uses the container runtime defaults for
+ The default value is Default which uses the container runtime defaults for
readonly paths and masked paths.
This requires the ProcMountType feature flag to be enabled.
Note that this field cannot be set when spec.os.name is windows.
@@ -4534,7 +4636,6 @@ spec:
type indicates which kind of seccomp profile will be applied.
Valid options are:
-
Localhost - a profile defined in a file on the node should be used.
RuntimeDefault - the container runtime default profile should be used.
Unconfined - no profile should be applied.
@@ -4610,10 +4711,8 @@ spec:
RecursiveReadOnly specifies whether read-only mounts should be handled
recursively.
-
If ReadOnly is false, this field has no meaning and must be unspecified.
-
If ReadOnly is true, and this field is set to Disabled, the mount is not made
recursively read-only. If this field is set to IfPossible, the mount is made
recursively read-only, if it is supported by the container runtime. If this
@@ -4621,11 +4720,9 @@ spec:
supported by the container runtime, otherwise the pod will not be started and
an error will be generated to indicate the reason.
-
If this field is set to IfPossible or Enabled, MountPropagation must be set to
None (or be unspecified, which defaults to None).
-
If this field is not specified, it is treated as an equivalent of Disabled.
type: string
subPath:
@@ -4723,9 +4820,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap
@@ -4795,9 +4890,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret
@@ -4837,9 +4930,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap
@@ -4862,9 +4953,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret
@@ -4903,8 +4992,8 @@ spec:
More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
properties:
exec:
- description: Exec specifies the action to
- take.
+ description: Exec specifies a command to
+ execute in the container.
properties:
command:
description: |-
@@ -4919,7 +5008,7 @@ spec:
x-kubernetes-list-type: atomic
type: object
httpGet:
- description: HTTPGet specifies the http
+ description: HTTPGet specifies an HTTP GET
request to perform.
properties:
host:
@@ -4973,9 +5062,8 @@ spec:
- port
type: object
sleep:
- description: Sleep represents the duration
- that the container should sleep before
- being terminated.
+ description: Sleep represents a duration
+ that the container should sleep.
properties:
seconds:
description: Seconds is the number of
@@ -4988,8 +5076,8 @@ spec:
tcpSocket:
description: |-
Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept
- for the backward compatibility. There are no validation of this field and
- lifecycle hooks will fail in runtime when tcp handler is specified.
+ for backward compatibility. There is no validation of this field and
+ lifecycle hooks will fail at runtime when it is specified.
properties:
host:
description: 'Optional: Host name to
@@ -5021,8 +5109,8 @@ spec:
More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
properties:
exec:
- description: Exec specifies the action to
- take.
+ description: Exec specifies a command to
+ execute in the container.
properties:
command:
description: |-
@@ -5037,7 +5125,7 @@ spec:
x-kubernetes-list-type: atomic
type: object
httpGet:
- description: HTTPGet specifies the http
+ description: HTTPGet specifies an HTTP GET
request to perform.
properties:
host:
@@ -5091,9 +5179,8 @@ spec:
- port
type: object
sleep:
- description: Sleep represents the duration
- that the container should sleep before
- being terminated.
+ description: Sleep represents a duration
+ that the container should sleep.
properties:
seconds:
description: Seconds is the number of
@@ -5106,8 +5193,8 @@ spec:
tcpSocket:
description: |-
Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept
- for the backward compatibility. There are no validation of this field and
- lifecycle hooks will fail in runtime when tcp handler is specified.
+ for backward compatibility. There is no validation of this field and
+ lifecycle hooks will fail at runtime when it is specified.
properties:
host:
description: 'Optional: Host name to
@@ -5135,7 +5222,8 @@ spec:
More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
properties:
exec:
- description: Exec specifies the action to take.
+ description: Exec specifies a command to execute
+ in the container.
properties:
command:
description: |-
@@ -5156,8 +5244,7 @@ spec:
format: int32
type: integer
grpc:
- description: GRPC specifies an action involving
- a GRPC port.
+ description: GRPC specifies a GRPC HealthCheckRequest.
properties:
port:
description: Port number of the gRPC service.
@@ -5165,18 +5252,18 @@ spec:
format: int32
type: integer
service:
+ default: ""
description: |-
Service is the name of the service to place in the gRPC HealthCheckRequest
(see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
-
If this is not specified, the default behavior is defined by gRPC.
type: string
required:
- port
type: object
httpGet:
- description: HTTPGet specifies the http request
+ description: HTTPGet specifies an HTTP GET request
to perform.
properties:
host:
@@ -5245,8 +5332,8 @@ spec:
format: int32
type: integer
tcpSocket:
- description: TCPSocket specifies an action involving
- a TCP port.
+ description: TCPSocket specifies a connection
+ to a TCP port.
properties:
host:
description: 'Optional: Host name to connect
@@ -5351,7 +5438,8 @@ spec:
More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
properties:
exec:
- description: Exec specifies the action to take.
+ description: Exec specifies a command to execute
+ in the container.
properties:
command:
description: |-
@@ -5372,8 +5460,7 @@ spec:
format: int32
type: integer
grpc:
- description: GRPC specifies an action involving
- a GRPC port.
+ description: GRPC specifies a GRPC HealthCheckRequest.
properties:
port:
description: Port number of the gRPC service.
@@ -5381,18 +5468,18 @@ spec:
format: int32
type: integer
service:
+ default: ""
description: |-
Service is the name of the service to place in the gRPC HealthCheckRequest
(see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
-
If this is not specified, the default behavior is defined by gRPC.
type: string
required:
- port
type: object
httpGet:
- description: HTTPGet specifies the http request
+ description: HTTPGet specifies an HTTP GET request
to perform.
properties:
host:
@@ -5461,8 +5548,8 @@ spec:
format: int32
type: integer
tcpSocket:
- description: TCPSocket specifies an action involving
- a TCP port.
+ description: TCPSocket specifies a connection
+ to a TCP port.
properties:
host:
description: 'Optional: Host name to connect
@@ -5535,11 +5622,9 @@ spec:
Claims lists the names of resources, defined in spec.resourceClaims,
that are used by this container.
-
This is an alpha field and requires enabling the
DynamicResourceAllocation feature gate.
-
This field is immutable. It can only be set for containers.
items:
description: ResourceClaim references one
@@ -5551,6 +5636,12 @@ spec:
the Pod where this field is used. It makes that resource available
inside a container.
type: string
+ request:
+ description: |-
+ Request is the name chosen for a request in the referenced claim.
+ If empty, everything from the claim is made available, otherwise
+ only the result of this request.
+ type: string
required:
- name
type: object
@@ -5674,7 +5765,7 @@ spec:
procMount:
description: |-
procMount denotes the type of proc mount to use for the containers.
- The default is DefaultProcMount which uses the container runtime defaults for
+ The default value is Default which uses the container runtime defaults for
readonly paths and masked paths.
This requires the ProcMountType feature flag to be enabled.
Note that this field cannot be set when spec.os.name is windows.
@@ -5756,7 +5847,6 @@ spec:
type indicates which kind of seccomp profile will be applied.
Valid options are:
-
Localhost - a profile defined in a file on the node should be used.
RuntimeDefault - the container runtime default profile should be used.
Unconfined - no profile should be applied.
@@ -5808,7 +5898,8 @@ spec:
More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
properties:
exec:
- description: Exec specifies the action to take.
+ description: Exec specifies a command to execute
+ in the container.
properties:
command:
description: |-
@@ -5829,8 +5920,7 @@ spec:
format: int32
type: integer
grpc:
- description: GRPC specifies an action involving
- a GRPC port.
+ description: GRPC specifies a GRPC HealthCheckRequest.
properties:
port:
description: Port number of the gRPC service.
@@ -5838,18 +5928,18 @@ spec:
format: int32
type: integer
service:
+ default: ""
description: |-
Service is the name of the service to place in the gRPC HealthCheckRequest
(see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
-
If this is not specified, the default behavior is defined by gRPC.
type: string
required:
- port
type: object
httpGet:
- description: HTTPGet specifies the http request
+ description: HTTPGet specifies an HTTP GET request
to perform.
properties:
host:
@@ -5918,8 +6008,8 @@ spec:
format: int32
type: integer
tcpSocket:
- description: TCPSocket specifies an action involving
- a TCP port.
+ description: TCPSocket specifies a connection
+ to a TCP port.
properties:
host:
description: 'Optional: Host name to connect
@@ -6060,10 +6150,8 @@ spec:
RecursiveReadOnly specifies whether read-only mounts should be handled
recursively.
-
If ReadOnly is false, this field has no meaning and must be unspecified.
-
If ReadOnly is true, and this field is set to Disabled, the mount is not made
recursively read-only. If this field is set to IfPossible, the mount is made
recursively read-only, if it is supported by the container runtime. If this
@@ -6071,11 +6159,9 @@ spec:
supported by the container runtime, otherwise the pod will not be started and
an error will be generated to indicate the reason.
-
If this field is set to IfPossible or Enabled, MountPropagation must be set to
None (or be unspecified, which defaults to None).
-
If this field is not specified, it is treated as an equivalent of Disabled.
type: string
subPath:
@@ -6122,7 +6208,6 @@ spec:
description: |-
Type is the type of merge operation to perform
-
By default, StrategicMerge is used as the patch type.
type: string
value:
@@ -6430,7 +6515,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -6445,7 +6530,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -6615,7 +6700,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -6630,7 +6715,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -6799,7 +6884,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -6814,7 +6899,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -6984,7 +7069,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -6999,7 +7084,7 @@ spec:
pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
- This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items:
type: string
type: array
@@ -7107,9 +7192,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -7163,12 +7246,10 @@ spec:
Some volume types allow the Kubelet to change the ownership of that volume
to be owned by the pod:
-
1. The owning GID will be the FSGroup
2. The setgid bit is set (new files created in the volume will be owned by FSGroup)
3. The permission bits are OR'd with rw-rw----
-
If unset, the Kubelet will not modify the ownership and permissions of any volume.
Note that this field cannot be set when spec.os.name is windows.
format: int64
@@ -7212,6 +7293,32 @@ spec:
Note that this field cannot be set when spec.os.name is windows.
format: int64
type: integer
+ seLinuxChangePolicy:
+ description: |-
+ seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod.
+ It has no effect on nodes that do not support SELinux or to volumes does not support SELinux.
+ Valid values are "MountOption" and "Recursive".
+
+ "Recursive" means relabeling of all files on all Pod volumes by the container runtime.
+ This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.
+
+ "MountOption" mounts all eligible Pod volumes with `-o context` mount option.
+ This requires all Pods that share the same volume to use the same SELinux label.
+ It is not possible to share the same volume among privileged and unprivileged Pods.
+ Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes
+ whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their
+ CSIDriver instance. Other volumes are always re-labelled recursively.
+ "MountOption" value is allowed only when SELinuxMount feature gate is enabled.
+
+ If not specified and SELinuxMount feature gate is enabled, "MountOption" is used.
+ If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes
+ and "Recursive" for all other volumes.
+
+ This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.
+
+ All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state.
+ Note that this field cannot be set when spec.os.name is windows.
+ type: string
seLinuxOptions:
description: |-
The SELinux context to be applied to all containers.
@@ -7255,7 +7362,6 @@ spec:
type indicates which kind of seccomp profile will be applied.
Valid options are:
-
Localhost - a profile defined in a file on the node should be used.
RuntimeDefault - the container runtime default profile should be used.
Unconfined - no profile should be applied.
@@ -7265,18 +7371,28 @@ spec:
type: object
supplementalGroups:
description: |-
- A list of groups applied to the first process run in each container, in addition
- to the container's primary GID, the fsGroup (if specified), and group memberships
- defined in the container image for the uid of the container process. If unspecified,
- no additional groups are added to any container. Note that group memberships
- defined in the container image for the uid of the container process are still effective,
- even if they are not included in this list.
+ A list of groups applied to the first process run in each container, in
+ addition to the container's primary GID and fsGroup (if specified). If
+ the SupplementalGroupsPolicy feature is enabled, the
+ supplementalGroupsPolicy field determines whether these are in addition
+ to or instead of any group memberships defined in the container image.
+ If unspecified, no additional groups are added, though group memberships
+ defined in the container image may still be used, depending on the
+ supplementalGroupsPolicy field.
Note that this field cannot be set when spec.os.name is windows.
items:
format: int64
type: integer
type: array
x-kubernetes-list-type: atomic
+ supplementalGroupsPolicy:
+ description: |-
+ Defines how supplemental groups of the first container processes are calculated.
+ Valid values are "Merge" and "Strict". If not specified, "Merge" is used.
+ (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled
+ and the container runtime must implement support for this feature.
+ Note that this field cannot be set when spec.os.name is windows.
+ type: string
sysctls:
description: |-
Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported
@@ -7440,7 +7556,6 @@ spec:
Keys that don't exist in the incoming pod labels will
be ignored. A null or empty list means only match against labelSelector.
-
This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default).
items:
type: string
@@ -7480,7 +7595,6 @@ spec:
Valid values are integers greater than 0.
When value is not nil, WhenUnsatisfiable must be DoNotSchedule.
-
For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same
labelSelector spread as 2/2/2:
| zone1 | zone2 | zone3 |
@@ -7498,7 +7612,6 @@ spec:
- Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations.
- Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.
-
If this value is nil, the behavior is equivalent to the Honor policy.
This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
type: string
@@ -7510,7 +7623,6 @@ spec:
has a toleration, are included.
- Ignore: node taints are ignored. All nodes are included.
-
If this value is nil, the behavior is equivalent to the Ignore policy.
This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
type: string
@@ -7567,6 +7679,8 @@ spec:
description: |-
awsElasticBlockStore represents an AWS Disk resource that is attached to a
kubelet's host machine and then exposed to the pod.
+ Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree
+ awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver.
More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
properties:
fsType:
@@ -7575,7 +7689,6 @@ spec:
Tip: Ensure that the filesystem type is supported by the host operating system.
Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
- TODO: how do we prevent errors in the filesystem from compromising the machine
type: string
partition:
description: |-
@@ -7599,9 +7712,10 @@ spec:
- volumeID
type: object
azureDisk:
- description: azureDisk represents an Azure Data
- Disk mount on the host and bind mount to the
- pod.
+ description: |-
+ azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.
+ Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type
+ are redirected to the disk.csi.azure.com CSI driver.
properties:
cachingMode:
description: 'cachingMode is the Host Caching
@@ -7616,6 +7730,7 @@ spec:
disk in the blob storage
type: string
fsType:
+ default: ext4
description: |-
fsType is Filesystem type to mount.
Must be a filesystem type supported by the host operating system.
@@ -7629,6 +7744,7 @@ spec:
availability set). defaults to shared'
type: string
readOnly:
+ default: false
description: |-
readOnly Defaults to false (read/write). ReadOnly here will force
the ReadOnly setting in VolumeMounts.
@@ -7638,9 +7754,10 @@ spec:
- diskURI
type: object
azureFile:
- description: azureFile represents an Azure File
- Service mount on the host and bind mount to
- the pod.
+ description: |-
+ azureFile represents an Azure File Service mount on the host and bind mount to the pod.
+ Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type
+ are redirected to the file.csi.azure.com CSI driver.
properties:
readOnly:
description: |-
@@ -7661,8 +7778,9 @@ spec:
- shareName
type: object
cephfs:
- description: cephFS represents a Ceph FS mount
- on the host that shares a pod's lifetime
+ description: |-
+ cephFS represents a Ceph FS mount on the host that shares a pod's lifetime.
+ Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported.
properties:
monitors:
description: |-
@@ -7700,9 +7818,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -7717,6 +7833,8 @@ spec:
cinder:
description: |-
cinder represents a cinder volume attached and mounted on kubelets host machine.
+ Deprecated: Cinder is deprecated. All operations for the in-tree cinder type
+ are redirected to the cinder.csi.openstack.org CSI driver.
More info: https://examples.k8s.io/mysql-cinder-pd/README.md
properties:
fsType:
@@ -7744,9 +7862,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -7819,9 +7935,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify whether the
@@ -7832,7 +7946,7 @@ spec:
csi:
description: csi (Container Storage Interface)
represents ephemeral storage that is handled
- by certain external CSI drivers (Beta feature).
+ by certain external CSI drivers.
properties:
driver:
description: |-
@@ -7860,9 +7974,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -8010,7 +8122,6 @@ spec:
The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts,
and deleted when the pod is removed.
-
Use this if:
a) the volume is only needed while the pod runs,
b) features of normal volumes like restoring from snapshot or capacity
@@ -8021,17 +8132,14 @@ spec:
information on the connection between this volume type
and PersistentVolumeClaim).
-
Use PersistentVolumeClaim or one of the vendor-specific
APIs for volumes that persist for longer than the lifecycle
of an individual pod.
-
Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to
be used that way - see the documentation of the driver for
more information.
-
A pod can use both types of ephemeral volumes and
persistent volumes at the same time.
properties:
@@ -8045,7 +8153,6 @@ spec:
entry. Pod validation will reject the pod if the concatenated name
is not valid for a PVC (for example, too long).
-
An existing PVC with that name that is not owned by the pod
will *not* be used for the pod to avoid using an unrelated
volume by mistake. Starting the pod is then blocked until
@@ -8055,11 +8162,9 @@ spec:
this should not be necessary, but it may be useful when
manually reconstructing a broken cluster.
-
This field is read-only and no changes will be made by Kubernetes
to the PVC after it has been created.
-
Required, must not be nil.
properties:
metadata:
@@ -8265,7 +8370,7 @@ spec:
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
exists.
More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
- (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).
type: string
volumeMode:
description: |-
@@ -8292,7 +8397,6 @@ spec:
fsType is the filesystem type to mount.
Must be a filesystem type supported by the host operating system.
Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
- TODO: how do we prevent errors in the filesystem from compromising the machine
type: string
lun:
description: 'lun is Optional: FC target
@@ -8324,6 +8428,7 @@ spec:
description: |-
flexVolume represents a generic volume resource that is
provisioned/attached using an exec based plugin.
+ Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead.
properties:
driver:
description: driver is the name of the driver
@@ -8361,9 +8466,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -8371,10 +8474,9 @@ spec:
- driver
type: object
flocker:
- description: flocker represents a Flocker volume
- attached to a kubelet's host machine. This
- depends on the Flocker control service being
- running
+ description: |-
+ flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running.
+ Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported.
properties:
datasetName:
description: |-
@@ -8391,6 +8493,8 @@ spec:
description: |-
gcePersistentDisk represents a GCE Disk resource that is attached to a
kubelet's host machine and then exposed to the pod.
+ Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree
+ gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver.
More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
properties:
fsType:
@@ -8399,7 +8503,6 @@ spec:
Tip: Ensure that the filesystem type is supported by the host operating system.
Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
- TODO: how do we prevent errors in the filesystem from compromising the machine
type: string
partition:
description: |-
@@ -8427,7 +8530,7 @@ spec:
gitRepo:
description: |-
gitRepo represents a git repository at a particular revision.
- DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an
+ Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an
EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir
into the Pod's container.
properties:
@@ -8451,6 +8554,7 @@ spec:
glusterfs:
description: |-
glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.
+ Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported.
More info: https://examples.k8s.io/volumes/glusterfs/README.md
properties:
endpoints:
@@ -8480,9 +8584,6 @@ spec:
used for system agents or other privileged things that are allowed
to see the host machine. Most containers will NOT need this.
More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath
- ---
- TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not
- mount host directories as read/write.
properties:
path:
description: |-
@@ -8499,6 +8600,41 @@ spec:
required:
- path
type: object
+ image:
+ description: |-
+ image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine.
+ The volume is resolved at pod startup depending on which PullPolicy value is provided:
+
+ - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.
+ - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.
+ - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.
+
+ The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation.
+ A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message.
+ The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field.
+ The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images.
+ The volume will be mounted read-only (ro) and non-executable files (noexec).
+ Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath).
+ The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.
+ properties:
+ pullPolicy:
+ description: |-
+ Policy for pulling OCI objects. Possible values are:
+ Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.
+ Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.
+ IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.
+ Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.
+ type: string
+ reference:
+ description: |-
+ Required: Image or artifact reference to be used.
+ Behaves in the same way as pod.spec.containers[*].image.
+ Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets.
+ More info: https://kubernetes.io/docs/concepts/containers/images
+ This field is optional to allow higher level config management to default or override
+ container images in workload controllers like Deployments and StatefulSets.
+ type: string
+ type: object
iscsi:
description: |-
iscsi represents an ISCSI Disk resource that is attached to a
@@ -8519,7 +8655,6 @@ spec:
Tip: Ensure that the filesystem type is supported by the host operating system.
Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi
- TODO: how do we prevent errors in the filesystem from compromising the machine
type: string
initiatorName:
description: |-
@@ -8532,6 +8667,7 @@ spec:
Name.
type: string
iscsiInterface:
+ default: default
description: |-
iscsiInterface is the interface Name that uses an iSCSI transport.
Defaults to 'default' (tcp).
@@ -8565,9 +8701,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -8632,9 +8766,9 @@ spec:
- claimName
type: object
photonPersistentDisk:
- description: photonPersistentDisk represents
- a PhotonController persistent disk attached
- and mounted on kubelets host machine
+ description: |-
+ photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine.
+ Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported.
properties:
fsType:
description: |-
@@ -8650,9 +8784,11 @@ spec:
- pdID
type: object
portworxVolume:
- description: portworxVolume represents a portworx
- volume attached and mounted on kubelets host
- machine
+ description: |-
+ portworxVolume represents a portworx volume attached and mounted on kubelets host machine.
+ Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type
+ are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate
+ is on.
properties:
fsType:
description: |-
@@ -8688,25 +8824,24 @@ spec:
format: int32
type: integer
sources:
- description: sources is the list of volume
- projections
+ description: |-
+ sources is the list of volume projections. Each entry in this list
+ handles one source.
items:
- description: Projection that may be projected
- along with other supported volume types
+ description: |-
+ Projection that may be projected along with other supported volume types.
+ Exactly one of these fields must be set.
properties:
clusterTrustBundle:
description: |-
ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field
of ClusterTrustBundle objects in an auto-updating file.
-
Alpha, gated by the ClusterTrustBundleProjection feature gate.
-
ClusterTrustBundle objects can either be selected by name, or by the
combination of signer name and a label selector.
-
Kubelet performs aggressive normalization of the PEM contents written
into the pod filesystem. Esoteric PEM features such as inter-block
comments and block headers are stripped. Certificates are deduplicated.
@@ -8845,9 +8980,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional specify
@@ -9001,9 +9134,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: optional field specify
@@ -9047,8 +9178,9 @@ spec:
x-kubernetes-list-type: atomic
type: object
quobyte:
- description: quobyte represents a Quobyte mount
- on the host that shares a pod's lifetime
+ description: |-
+ quobyte represents a Quobyte mount on the host that shares a pod's lifetime.
+ Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported.
properties:
group:
description: |-
@@ -9087,6 +9219,7 @@ spec:
rbd:
description: |-
rbd represents a Rados Block Device mount on the host that shares a pod's lifetime.
+ Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported.
More info: https://examples.k8s.io/volumes/rbd/README.md
properties:
fsType:
@@ -9095,7 +9228,6 @@ spec:
Tip: Ensure that the filesystem type is supported by the host operating system.
Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd
- TODO: how do we prevent errors in the filesystem from compromising the machine
type: string
image:
description: |-
@@ -9103,6 +9235,7 @@ spec:
More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
type: string
keyring:
+ default: /etc/ceph/keyring
description: |-
keyring is the path to key ring for RBDUser.
Default is /etc/ceph/keyring.
@@ -9117,6 +9250,7 @@ spec:
type: array
x-kubernetes-list-type: atomic
pool:
+ default: rbd
description: |-
pool is the rados pool name.
Default is rbd.
@@ -9142,13 +9276,12 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
user:
+ default: admin
description: |-
user is the rados user name.
Default is admin.
@@ -9159,11 +9292,12 @@ spec:
- monitors
type: object
scaleIO:
- description: scaleIO represents a ScaleIO persistent
- volume attached and mounted on Kubernetes
- nodes.
+ description: |-
+ scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.
+ Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported.
properties:
fsType:
+ default: xfs
description: |-
fsType is the filesystem type to mount.
Must be a filesystem type supported by the host operating system.
@@ -9196,9 +9330,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -9208,6 +9340,7 @@ spec:
false
type: boolean
storageMode:
+ default: ThinProvisioned
description: |-
storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.
Default is ThinProvisioned.
@@ -9297,9 +9430,9 @@ spec:
type: string
type: object
storageos:
- description: storageOS represents a StorageOS
- volume attached and mounted on Kubernetes
- nodes.
+ description: |-
+ storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.
+ Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported.
properties:
fsType:
description: |-
@@ -9324,9 +9457,7 @@ spec:
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
- TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
@@ -9346,9 +9477,10 @@ spec:
type: string
type: object
vsphereVolume:
- description: vsphereVolume represents a vSphere
- volume attached and mounted on kubelets host
- machine
+ description: |-
+ vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine.
+ Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type
+ are redirected to the csi.vsphere.vmware.com CSI driver.
properties:
fsType:
description: |-
@@ -9391,9 +9523,6 @@ spec:
description: |-
Rolling update config params. Present only if DeploymentStrategyType =
RollingUpdate.
- ---
- TODO: Update this to follow our convention for oneOf, whatever we decide it
- to be.
properties:
maxSurge:
anyOf:
@@ -9586,7 +9715,6 @@ spec:
each pod of the current scale target (e.g. CPU or memory). Such metrics are
built in to Kubernetes, and have special scaling options on top of those
available to normal per-pod metrics using the "pods" source.
- This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.
properties:
container:
description: container is the name of the container
@@ -10044,8 +10172,6 @@ spec:
description: |-
type is the type of metric source. It should be one of "ContainerResource", "External",
"Object", "Pods" or "Resource", each mapping to a matching field in the object.
- Note: "ContainerResource" type is available on when the feature-gate
- HPAContainerMetrics is enabled
type: string
required:
- type
@@ -10060,6 +10186,23 @@ spec:
x-kubernetes-validations:
- message: minReplicas must be greater than 0
rule: self > 0
+ patch:
+ description: Patch defines how to perform the patch operation
+ to the HorizontalPodAutoscaler
+ properties:
+ type:
+ description: |-
+ Type is the type of merge operation to perform
+
+ By default, StrategicMerge is used as the patch type.
+ type: string
+ value:
+ description: Object contains the raw configuration
+ for merged object
+ x-kubernetes-preserve-unknown-fields: true
+ required:
+ - value
+ type: object
required:
- maxReplicas
type: object
@@ -10077,6 +10220,23 @@ spec:
and resilience during maintenance operations.
format: int32
type: integer
+ patch:
+ description: Patch defines how to perform the patch operation
+ to the PodDisruptionBudget
+ properties:
+ type:
+ description: |-
+ Type is the type of merge operation to perform
+
+ By default, StrategicMerge is used as the patch type.
+ type: string
+ value:
+ description: Object contains the raw configuration
+ for merged object
+ x-kubernetes-preserve-unknown-fields: true
+ required:
+ - value
+ type: object
type: object
envoyService:
description: |-
@@ -10109,6 +10269,13 @@ spec:
- Local
- Cluster
type: string
+ labels:
+ additionalProperties:
+ type: string
+ description: |-
+ Labels that should be appended to the service.
+ By default, no labels are appended.
+ type: object
loadBalancerClass:
description: |-
LoadBalancerClass, when specified, allows for choosing the LoadBalancer provider
@@ -10147,7 +10314,6 @@ spec:
description: |-
Type is the type of merge operation to perform
-
By default, StrategicMerge is used as the patch type.
type: string
value:
@@ -10207,6 +10373,7 @@ spec:
optional auxiliary control planes. Supported types are "Kubernetes".
enum:
- Kubernetes
+ - Custom
type: string
required:
- type
@@ -10223,12 +10390,12 @@ spec:
drainTimeout:
description: |-
DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds.
- If unspecified, defaults to 600 seconds.
+ If unspecified, defaults to 60 seconds.
type: string
minDrainDuration:
description: |-
MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
- If unspecified, defaults to 5 seconds.
+ If unspecified, defaults to 10 seconds.
type: string
type: object
telemetry:
@@ -10292,6 +10459,7 @@ spec:
Invalid [CEL](https://www.envoyproxy.io/docs/envoy/latest/xds/type/v3/cel.proto.html#common-expression-language-cel-proto) expressions will be ignored.
items:
type: string
+ maxItems: 10
type: array
sinks:
description: Sinks defines the sinks of accesslog.
@@ -10303,14 +10471,97 @@ spec:
description: ALS defines the gRPC Access Log Service
(ALS) sink.
properties:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+ Defaults to "Service" when not specified.
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+ Support: Core (Services with a type other than ExternalName)
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind
+ == ''Service'') ? has(self.port) : true'
backendRefs:
description: |-
- BackendRefs references a Kubernetes object that represents the gRPC service to which
- the access logs will be sent. Currently only Service is supported.
+ BackendRefs references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
items:
description: BackendRef defines how an ObjectReference
that is specific to BackendRef.
properties:
+ fallback:
+ description: |-
+ Fallback indicates whether the backend is designated as a fallback.
+ Multiple fallback backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -10325,20 +10576,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -10355,13 +10602,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -10385,48 +10630,784 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind
== ''Service'') ? has(self.port) : true'
- maxItems: 1
- minItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: BackendRefs only supports Service
- kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core
- group.
- rule: self.all(f, f.group == '')
- http:
- description: HTTP defines additional configuration
- specific to HTTP access logs.
- properties:
- requestHeaders:
- description: RequestHeaders defines request
- headers to include in log entries sent
- to the access log service.
- items:
- type: string
- type: array
- responseHeaders:
- description: ResponseHeaders defines response
- headers to include in log entries sent
- to the access log service.
- items:
- type: string
- type: array
- responseTrailers:
- description: ResponseTrailers defines
- response trailers to include in log
- entries sent to the access log service.
- items:
- type: string
- type: array
- type: object
- logName:
+ backendSettings:
description: |-
- LogName defines the friendly name of the access log to be returned in
- StreamAccessLogsMessage.Identifier. This allows the access log server
- to differentiate between different access logs coming from the same Envoy.
- minLength: 1
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of
+ connections that Envoy will establish
+ to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of
+ parallel requests that Envoy will
+ make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of
+ parallel retries that Envoy will
+ make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of
+ pending requests that Envoy will
+ queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend
+ connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution
+ settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway
+ to perform active health checking on
+ backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold
+ defines the number of healthy
+ health checks required before
+ a backend host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse
+ defines a list of HTTP expected
+ responses to match.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus
+ defines the http status
+ code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines
+ the HTTP path that will
+ be requested during health
+ checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines
+ the time between active health
+ checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines
+ the expected response payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ send:
+ description: Send defines
+ the request payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the
+ time to wait for a health check
+ response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the
+ type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold
+ defines the number of unhealthy
+ health checks required before
+ a backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type
+ is HTTP, http field needs to be
+ set.
+ rule: 'self.type == ''HTTP'' ? has(self.http)
+ : !has(self.http)'
+ - message: If Health Checker type
+ is TCP, tcp field needs to be
+ set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp)
+ : !has(self.tcp)'
+ - message: The grpc field can only
+ be set if the Health Checker type
+ is GRPC.
+ rule: 'has(self.grpc) ? self.type
+ == ''GRPC'' : true'
+ passive:
+ description: Passive passive check
+ configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime
+ defines the base duration for
+ which a host will be ejected
+ on consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors
+ sets the number of consecutive
+ 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors
+ sets the number of consecutive
+ gateway errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines
+ the time between passive health
+ checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent
+ sets the maximum percentage
+ of hosts in a cluster that can
+ be ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors
+ enables splitting of errors
+ between external and local origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration
+ for backend connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures
+ the cookie hash policy when
+ the consistent hash type is
+ set to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes
+ to set for the generated
+ cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures
+ the header hash policy when
+ the consistent hash type is
+ set to Header.
+ properties:
+ name:
+ description: Name of the header
+ to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for
+ consistent hashing, must be
+ prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type
+ is header, the header field must
+ be set.
+ rule: 'self.type == ''Header'' ?
+ has(self.header) : !has(self.header)'
+ - message: If consistent hash type
+ is cookie, the cookie field must
+ be set.
+ rule: 'self.type == ''Cookie'' ?
+ has(self.cookie) : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash,
+ consistentHash field needs to be set.
+ rule: 'self.type == ''ConsistentHash''
+ ? has(self.consistentHash) : !has(self.consistentHash)'
+ - message: Currently SlowStart is only
+ supported for RoundRobin and LeastRequest
+ load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the
+ Proxy Protocol when communicating with
+ the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ retry:
+ description: |-
+ Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
+ If not set, retry will be disabled.
+ properties:
+ numRetries:
+ default: 2
+ description: NumRetries is the number
+ of retries to be attempted. Defaults
+ to 2.
+ format: int32
+ minimum: 0
+ type: integer
+ perRetry:
+ description: PerRetry is the retry
+ policy to be applied per retry attempt.
+ properties:
+ backOff:
+ description: |-
+ Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
+ back-off algorithm for retries. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries
+ properties:
+ baseInterval:
+ description: BaseInterval
+ is the base interval between
+ retries.
+ format: duration
+ type: string
+ maxInterval:
+ description: |-
+ MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
+ The default is 10 times the base_interval
+ format: duration
+ type: string
+ type: object
+ timeout:
+ description: Timeout is the timeout
+ per retry attempt.
+ format: duration
+ type: string
+ type: object
+ retryOn:
+ description: |-
+ RetryOn specifies the retry trigger condition.
+
+ If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503).
+ properties:
+ httpStatusCodes:
+ description: |-
+ HttpStatusCodes specifies the http status codes to be retried.
+ The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
+ items:
+ description: HTTPStatus defines
+ the http status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ triggers:
+ description: Triggers specifies
+ the retry trigger condition(Http/Grpc).
+ items:
+ description: TriggerEnum specifies
+ the conditions that trigger
+ retries.
+ enum:
+ - 5xx
+ - gateway-error
+ - reset
+ - connect-failure
+ - retriable-4xx
+ - refused-stream
+ - retriable-status-codes
+ - cancelled
+ - deadline-exceeded
+ - internal
+ - resource-exhausted
+ - unavailable
+ type: string
+ type: array
+ type: object
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the
+ backend connections.
+ properties:
+ http:
+ description: Timeout settings for
+ HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ requestTimeout:
+ description: RequestTimeout is
+ the time until which entire
+ response is received from the
+ upstream.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for
+ TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
+ http:
+ description: HTTP defines additional configuration
+ specific to HTTP access logs.
+ properties:
+ requestHeaders:
+ description: RequestHeaders defines request
+ headers to include in log entries sent
+ to the access log service.
+ items:
+ type: string
+ type: array
+ responseHeaders:
+ description: ResponseHeaders defines response
+ headers to include in log entries sent
+ to the access log service.
+ items:
+ type: string
+ type: array
+ responseTrailers:
+ description: ResponseTrailers defines
+ response trailers to include in log
+ entries sent to the access log service.
+ items:
+ type: string
+ type: array
+ type: object
+ logName:
+ description: |-
+ LogName defines the friendly name of the access log to be returned in
+ StreamAccessLogsMessage.Identifier. This allows the access log server
+ to differentiate between different access logs coming from the same Envoy.
+ minLength: 1
type: string
type:
description: Type defines the type of accesslog.
@@ -10436,13 +11417,24 @@ spec:
- TCP
type: string
required:
- - backendRefs
- type
type: object
x-kubernetes-validations:
- message: The http field may only be set when
type is HTTP.
rule: self.type == 'HTTP' || !has(self.http)
+ - message: BackendRefs must be used, backendRef
+ is not supported.
+ rule: '!has(self.backendRef)'
+ - message: must have at least one backend in backendRefs
+ rule: has(self.backendRefs) && self.backendRefs.size()
+ > 0
+ - message: BackendRefs only supports Service kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f,
+ f.kind == ''Service'') : true'
+ - message: BackendRefs only supports Core group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f,
+ f.group == "")) : true'
file:
description: File defines the file accesslog sink.
properties:
@@ -10456,15 +11448,97 @@ spec:
description: OpenTelemetry defines the OpenTelemetry
accesslog sink.
properties:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+ Defaults to "Service" when not specified.
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+ Support: Core (Services with a type other than ExternalName)
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind
+ == ''Service'') ? has(self.port) : true'
backendRefs:
description: |-
BackendRefs references a Kubernetes object that represents the
- backend server to which the access log will be sent.
- Only Service kind is supported for now.
+ backend server to which the authorization request will be sent.
items:
description: BackendRef defines how an ObjectReference
that is specific to BackendRef.
properties:
+ fallback:
+ description: |-
+ Fallback indicates whether the backend is designated as a fallback.
+ Multiple fallback backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -10479,20 +11553,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -10509,13 +11579,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -10539,14 +11607,752 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind
== ''Service'') ? has(self.port) : true'
- maxItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: only support Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core
- group.
- rule: self.all(f, f.group == '')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of
+ connections that Envoy will establish
+ to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of
+ parallel requests that Envoy will
+ make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of
+ parallel retries that Envoy will
+ make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of
+ pending requests that Envoy will
+ queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend
+ connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution
+ settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway
+ to perform active health checking on
+ backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold
+ defines the number of healthy
+ health checks required before
+ a backend host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse
+ defines a list of HTTP expected
+ responses to match.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus
+ defines the http status
+ code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines
+ the HTTP path that will
+ be requested during health
+ checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines
+ the time between active health
+ checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines
+ the expected response payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ send:
+ description: Send defines
+ the request payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the
+ time to wait for a health check
+ response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the
+ type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold
+ defines the number of unhealthy
+ health checks required before
+ a backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type
+ is HTTP, http field needs to be
+ set.
+ rule: 'self.type == ''HTTP'' ? has(self.http)
+ : !has(self.http)'
+ - message: If Health Checker type
+ is TCP, tcp field needs to be
+ set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp)
+ : !has(self.tcp)'
+ - message: The grpc field can only
+ be set if the Health Checker type
+ is GRPC.
+ rule: 'has(self.grpc) ? self.type
+ == ''GRPC'' : true'
+ passive:
+ description: Passive passive check
+ configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime
+ defines the base duration for
+ which a host will be ejected
+ on consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors
+ sets the number of consecutive
+ 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors
+ sets the number of consecutive
+ gateway errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines
+ the time between passive health
+ checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent
+ sets the maximum percentage
+ of hosts in a cluster that can
+ be ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors
+ enables splitting of errors
+ between external and local origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration
+ for backend connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures
+ the cookie hash policy when
+ the consistent hash type is
+ set to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes
+ to set for the generated
+ cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures
+ the header hash policy when
+ the consistent hash type is
+ set to Header.
+ properties:
+ name:
+ description: Name of the header
+ to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for
+ consistent hashing, must be
+ prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type
+ is header, the header field must
+ be set.
+ rule: 'self.type == ''Header'' ?
+ has(self.header) : !has(self.header)'
+ - message: If consistent hash type
+ is cookie, the cookie field must
+ be set.
+ rule: 'self.type == ''Cookie'' ?
+ has(self.cookie) : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash,
+ consistentHash field needs to be set.
+ rule: 'self.type == ''ConsistentHash''
+ ? has(self.consistentHash) : !has(self.consistentHash)'
+ - message: Currently SlowStart is only
+ supported for RoundRobin and LeastRequest
+ load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the
+ Proxy Protocol when communicating with
+ the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ retry:
+ description: |-
+ Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
+ If not set, retry will be disabled.
+ properties:
+ numRetries:
+ default: 2
+ description: NumRetries is the number
+ of retries to be attempted. Defaults
+ to 2.
+ format: int32
+ minimum: 0
+ type: integer
+ perRetry:
+ description: PerRetry is the retry
+ policy to be applied per retry attempt.
+ properties:
+ backOff:
+ description: |-
+ Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
+ back-off algorithm for retries. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries
+ properties:
+ baseInterval:
+ description: BaseInterval
+ is the base interval between
+ retries.
+ format: duration
+ type: string
+ maxInterval:
+ description: |-
+ MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
+ The default is 10 times the base_interval
+ format: duration
+ type: string
+ type: object
+ timeout:
+ description: Timeout is the timeout
+ per retry attempt.
+ format: duration
+ type: string
+ type: object
+ retryOn:
+ description: |-
+ RetryOn specifies the retry trigger condition.
+
+ If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503).
+ properties:
+ httpStatusCodes:
+ description: |-
+ HttpStatusCodes specifies the http status codes to be retried.
+ The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
+ items:
+ description: HTTPStatus defines
+ the http status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ triggers:
+ description: Triggers specifies
+ the retry trigger condition(Http/Grpc).
+ items:
+ description: TriggerEnum specifies
+ the conditions that trigger
+ retries.
+ enum:
+ - 5xx
+ - gateway-error
+ - reset
+ - connect-failure
+ - retriable-4xx
+ - refused-stream
+ - retriable-status-codes
+ - cancelled
+ - deadline-exceeded
+ - internal
+ - resource-exhausted
+ - unavailable
+ type: string
+ type: array
+ type: object
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the
+ backend connections.
+ properties:
+ http:
+ description: Timeout settings for
+ HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ requestTimeout:
+ description: RequestTimeout is
+ the time until which entire
+ response is received from the
+ upstream.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for
+ TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
host:
description: |-
Host define the extension service hostname.
@@ -10572,6 +12378,15 @@ spec:
- message: host or backendRefs needs to be set
rule: has(self.host) || self.backendRefs.size()
> 0
+ - message: BackendRefs must be used, backendRef
+ is not supported.
+ rule: '!has(self.backendRef)'
+ - message: BackendRefs only supports Service kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f,
+ f.kind == ''Service'') : true'
+ - message: BackendRefs only supports Core group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f,
+ f.group == "")) : true'
type:
description: Type defines the type of accesslog
sink.
@@ -10596,6 +12411,17 @@ spec:
maxItems: 50
minItems: 1
type: array
+ type:
+ description: |-
+ Type defines the component emitting the accesslog, such as Listener and Route.
+ If type not defined, the setting would apply to:
+ (1) All Routes.
+ (2) Listeners if and only if Envoy does not find a matching route for a request.
+ If type is defined, the accesslog settings would apply to the relevant component (as-is).
+ enum:
+ - Listener
+ - Route
+ type: string
required:
- sinks
type: object
@@ -10612,6 +12438,11 @@ spec:
EnablePerEndpointStats enables per endpoint envoy stats metrics.
Please use with caution.
type: boolean
+ enableRequestResponseSizesStats:
+ description: EnableRequestResponseSizesStats enables publishing
+ of histograms tracking header and body sizes of requests
+ and responses.
+ type: boolean
enableVirtualHostStats:
description: EnableVirtualHostStats enables envoy stat metrics
for virtual hosts.
@@ -10688,15 +12519,97 @@ spec:
OpenTelemetry defines the configuration for OpenTelemetry sink.
It's required if the sink type is OpenTelemetry.
properties:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+ Defaults to "Service" when not specified.
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+ Support: Core (Services with a type other than ExternalName)
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind ==
+ ''Service'') ? has(self.port) : true'
backendRefs:
description: |-
BackendRefs references a Kubernetes object that represents the
- backend server to which the metric will be sent.
- Only Service kind is supported for now.
+ backend server to which the authorization request will be sent.
items:
description: BackendRef defines how an ObjectReference
that is specific to BackendRef.
properties:
+ fallback:
+ description: |-
+ Fallback indicates whether the backend is designated as a fallback.
+ Multiple fallback backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -10711,20 +12624,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -10740,13 +12649,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -10770,13 +12677,717 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind ==
''Service'') ? has(self.port) : true'
- maxItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: only support Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core group.
- rule: self.all(f, f.group == '')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections
+ that Envoy will establish to the referenced
+ backend defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel
+ requests that Envoy will make to the referenced
+ backend defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel
+ retries that Envoy will make to the referenced
+ backend defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending
+ requests that Envoy will queue to the
+ referenced backend defined within a xRoute
+ rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection
+ settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform
+ active health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines
+ the number of healthy health checks
+ required before a backend host is
+ marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines
+ a list of HTTP expected responses
+ to match.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in
+ plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the
+ type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text,
+ text field needs to be set.
+ rule: 'self.type == ''Text'' ?
+ has(self.text) : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines
+ the http status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP
+ path that will be requested during
+ health checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time
+ between active health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the
+ expected response payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in
+ plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the
+ type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text,
+ text field needs to be set.
+ rule: 'self.type == ''Text'' ?
+ has(self.text) : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ send:
+ description: Send defines the request
+ payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in
+ plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the
+ type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text,
+ text field needs to be set.
+ rule: 'self.type == ''Text'' ?
+ has(self.text) : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time
+ to wait for a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of
+ health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines
+ the number of unhealthy health checks
+ required before a backend host is
+ marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP,
+ http field needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http)
+ : !has(self.http)'
+ - message: If Health Checker type is TCP,
+ tcp field needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp)
+ : !has(self.tcp)'
+ - message: The grpc field can only be set
+ if the Health Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC''
+ : true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines
+ the base duration for which a host
+ will be ejected on consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets
+ the number of consecutive 5xx errors
+ triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors
+ sets the number of consecutive gateway
+ errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time
+ between passive health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets
+ the maximum percentage of hosts in
+ a cluster that can be ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors
+ enables splitting of errors between
+ external and local origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration
+ for backend connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie
+ hash policy when the consistent hash
+ type is set to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes
+ to set for the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header
+ hash policy when the consistent hash
+ type is set to Header.
+ properties:
+ name:
+ description: Name of the header
+ to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent
+ hashing, must be prime number limited
+ to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header,
+ the header field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie,
+ the cookie field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash,
+ consistentHash field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported
+ for RoundRobin and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy
+ Protocol when communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ retry:
+ description: |-
+ Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
+ If not set, retry will be disabled.
+ properties:
+ numRetries:
+ default: 2
+ description: NumRetries is the number of
+ retries to be attempted. Defaults to 2.
+ format: int32
+ minimum: 0
+ type: integer
+ perRetry:
+ description: PerRetry is the retry policy
+ to be applied per retry attempt.
+ properties:
+ backOff:
+ description: |-
+ Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
+ back-off algorithm for retries. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries
+ properties:
+ baseInterval:
+ description: BaseInterval is the
+ base interval between retries.
+ format: duration
+ type: string
+ maxInterval:
+ description: |-
+ MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
+ The default is 10 times the base_interval
+ format: duration
+ type: string
+ type: object
+ timeout:
+ description: Timeout is the timeout
+ per retry attempt.
+ format: duration
+ type: string
+ type: object
+ retryOn:
+ description: |-
+ RetryOn specifies the retry trigger condition.
+
+ If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503).
+ properties:
+ httpStatusCodes:
+ description: |-
+ HttpStatusCodes specifies the http status codes to be retried.
+ The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
+ items:
+ description: HTTPStatus defines the
+ http status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ triggers:
+ description: Triggers specifies the
+ retry trigger condition(Http/Grpc).
+ items:
+ description: TriggerEnum specifies
+ the conditions that trigger retries.
+ enum:
+ - 5xx
+ - gateway-error
+ - reset
+ - connect-failure
+ - retriable-4xx
+ - refused-stream
+ - retriable-status-codes
+ - cancelled
+ - deadline-exceeded
+ - internal
+ - resource-exhausted
+ - unavailable
+ type: string
+ type: array
+ type: object
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend
+ connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ requestTimeout:
+ description: RequestTimeout is the time
+ until which entire response is received
+ from the upstream.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
host:
description: |-
Host define the service hostname.
@@ -10796,6 +13407,15 @@ spec:
- message: host or backendRefs needs to be set
rule: has(self.host) || self.backendRefs.size() >
0
+ - message: BackendRefs must be used, backendRef is not
+ supported.
+ rule: '!has(self.backendRef)'
+ - message: only supports Service kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f,
+ f.kind == ''Service'') : true'
+ - message: BackendRefs only supports Core group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f,
+ f.group == "")) : true'
type:
default: OpenTelemetry
description: |-
@@ -10812,6 +13432,7 @@ spec:
field needs to be set.
rule: 'self.type == ''OpenTelemetry'' ? has(self.openTelemetry)
: !has(self.openTelemetry)'
+ maxItems: 16
type: array
type: object
tracing:
@@ -10884,15 +13505,97 @@ spec:
provider:
description: Provider defines the tracing provider.
properties:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+ Defaults to "Service" when not specified.
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+ Support: Core (Services with a type other than ExternalName)
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind == ''Service'')
+ ? has(self.port) : true'
backendRefs:
description: |-
BackendRefs references a Kubernetes object that represents the
- backend server to which the trace will be sent.
- Only Service kind is supported for now.
+ backend server to which the authorization request will be sent.
items:
description: BackendRef defines how an ObjectReference
that is specific to BackendRef.
properties:
+ fallback:
+ description: |-
+ Fallback indicates whether the backend is designated as a fallback.
+ Multiple fallback backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -10907,20 +13610,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -10936,13 +13635,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -10966,13 +13663,712 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
- maxItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: only support Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core group.
- rule: self.all(f, f.group == '')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections
+ that Envoy will establish to the referenced
+ backend defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel requests
+ that Envoy will make to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel retries
+ that Envoy will make to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending requests
+ that Envoy will queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection
+ settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform
+ active health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines the
+ number of healthy health checks required
+ before a backend host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines
+ a list of HTTP expected responses to
+ match.
+ properties:
+ binary:
+ description: Binary payload base64
+ encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain
+ text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type
+ of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text
+ field needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines the
+ http status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP path
+ that will be requested during health
+ checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ active health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the expected
+ response payload.
+ properties:
+ binary:
+ description: Binary payload base64
+ encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain
+ text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type
+ of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text
+ field needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ send:
+ description: Send defines the request
+ payload.
+ properties:
+ binary:
+ description: Binary payload base64
+ encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain
+ text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type
+ of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text
+ field needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time to wait
+ for a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of health
+ checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines the
+ number of unhealthy health checks required
+ before a backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP, http
+ field needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http)
+ : !has(self.http)'
+ - message: If Health Checker type is TCP, tcp
+ field needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp)
+ : !has(self.tcp)'
+ - message: The grpc field can only be set if the
+ Health Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC''
+ : true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines the
+ base duration for which a host will be ejected
+ on consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets the
+ number of consecutive 5xx errors triggering
+ ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors sets
+ the number of consecutive gateway errors
+ triggering ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ passive health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets the maximum
+ percentage of hosts in a cluster that can
+ be ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors
+ enables splitting of errors between external
+ and local origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration for
+ backend connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie
+ hash policy when the consistent hash type
+ is set to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes to
+ set for the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header
+ hash policy when the consistent hash type
+ is set to Header.
+ properties:
+ name:
+ description: Name of the header to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent
+ hashing, must be prime number limited to
+ 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header,
+ the header field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie,
+ the cookie field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash,
+ consistentHash field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported for
+ RoundRobin and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy Protocol
+ when communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ retry:
+ description: |-
+ Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
+ If not set, retry will be disabled.
+ properties:
+ numRetries:
+ default: 2
+ description: NumRetries is the number of retries
+ to be attempted. Defaults to 2.
+ format: int32
+ minimum: 0
+ type: integer
+ perRetry:
+ description: PerRetry is the retry policy to be
+ applied per retry attempt.
+ properties:
+ backOff:
+ description: |-
+ Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
+ back-off algorithm for retries. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries
+ properties:
+ baseInterval:
+ description: BaseInterval is the base
+ interval between retries.
+ format: duration
+ type: string
+ maxInterval:
+ description: |-
+ MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
+ The default is 10 times the base_interval
+ format: duration
+ type: string
+ type: object
+ timeout:
+ description: Timeout is the timeout per retry
+ attempt.
+ format: duration
+ type: string
+ type: object
+ retryOn:
+ description: |-
+ RetryOn specifies the retry trigger condition.
+
+ If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503).
+ properties:
+ httpStatusCodes:
+ description: |-
+ HttpStatusCodes specifies the http status codes to be retried.
+ The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
+ items:
+ description: HTTPStatus defines the http
+ status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ triggers:
+ description: Triggers specifies the retry
+ trigger condition(Http/Grpc).
+ items:
+ description: TriggerEnum specifies the conditions
+ that trigger retries.
+ enum:
+ - 5xx
+ - gateway-error
+ - reset
+ - connect-failure
+ - retriable-4xx
+ - refused-stream
+ - retriable-status-codes
+ - cancelled
+ - deadline-exceeded
+ - internal
+ - resource-exhausted
+ - unavailable
+ type: string
+ type: array
+ type: object
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ requestTimeout:
+ description: RequestTimeout is the time until
+ which entire response is received from the
+ upstream.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
host:
description: |-
Host define the provider service hostname.
@@ -10992,6 +14388,7 @@ spec:
enum:
- OpenTelemetry
- Zipkin
+ - Datadog
type: string
zipkin:
description: Zipkin defines the Zipkin tracing provider
@@ -11015,6 +14412,14 @@ spec:
x-kubernetes-validations:
- message: host or backendRefs needs to be set
rule: has(self.host) || self.backendRefs.size() > 0
+ - message: BackendRefs must be used, backendRef is not supported.
+ rule: '!has(self.backendRef)'
+ - message: only supports Service kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind
+ == ''Service'') : true'
+ - message: BackendRefs only supports Core group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f,
+ f.group == "")) : true'
samplingRate:
default: 100
description: |-
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_httproutefilters.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_httproutefilters.yaml
new file mode 100644
index 00000000000..195bf24ece8
--- /dev/null
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_httproutefilters.yaml
@@ -0,0 +1,220 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.1
+ name: httproutefilters.gateway.envoyproxy.io
+spec:
+ group: gateway.envoyproxy.io
+ names:
+ categories:
+ - envoy-gateway
+ kind: HTTPRouteFilter
+ listKind: HTTPRouteFilterList
+ plural: httproutefilters
+ shortNames:
+ - hrf
+ singular: httproutefilter
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: |-
+ HTTPRouteFilter is a custom Envoy Gateway HTTPRouteFilter which provides extended
+ traffic processing options such as path regex rewrite, direct response and more.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Spec defines the desired state of HTTPRouteFilter.
+ properties:
+ directResponse:
+ description: HTTPDirectResponseFilter defines the configuration to
+ return a fixed response.
+ properties:
+ body:
+ description: Body of the Response
+ properties:
+ inline:
+ description: Inline contains the value as an inline string.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Inline
+ - ValueRef
+ - enum:
+ - Inline
+ - ValueRef
+ default: Inline
+ description: |-
+ Type is the type of method to use to read the body value.
+ Valid values are Inline and ValueRef, default is Inline.
+ type: string
+ valueRef:
+ description: |-
+ ValueRef contains the contents of the body
+ specified as a local object reference.
+ Only a reference to ConfigMap is supported.
+
+ The value of key `response.body` in the ConfigMap will be used as the response body.
+ If the key is not found, the first value in the ConfigMap will be used.
+ properties:
+ group:
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ description: Kind is kind of the referent. For example
+ "HTTPRoute" or "Service".
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ required:
+ - group
+ - kind
+ - name
+ type: object
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: inline must be set for type Inline
+ rule: '(!has(self.type) || self.type == ''Inline'')? has(self.inline)
+ : true'
+ - message: valueRef must be set for type ValueRef
+ rule: '(has(self.type) && self.type == ''ValueRef'')? has(self.valueRef)
+ : true'
+ - message: only ConfigMap is supported for ValueRef
+ rule: 'has(self.valueRef) ? self.valueRef.kind == ''ConfigMap''
+ : true'
+ contentType:
+ description: Content Type of the response. This will be set in
+ the Content-Type header.
+ type: string
+ statusCode:
+ description: |-
+ Status Code of the HTTP response
+ If unset, defaults to 200.
+ type: integer
+ type: object
+ urlRewrite:
+ description: HTTPURLRewriteFilter define rewrites of HTTP URL components
+ such as path and host
+ properties:
+ hostname:
+ description: |-
+ Hostname is the value to be used to replace the Host header value during
+ forwarding.
+ properties:
+ header:
+ description: Header is the name of the header whose value
+ would be used to rewrite the Host header
+ type: string
+ type:
+ description: HTTPPathModifierType defines the type of Hostname
+ rewrite.
+ enum:
+ - Header
+ - Backend
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: header must be nil if the type is not Header
+ rule: '!(has(self.header) && self.type != ''Header'')'
+ - message: header must be specified for Header type
+ rule: '!(!has(self.header) && self.type == ''Header'')'
+ path:
+ description: Path defines a path rewrite.
+ properties:
+ replaceRegexMatch:
+ description: |-
+ ReplaceRegexMatch defines a path regex rewrite. The path portions matched by the regex pattern are replaced by the defined substitution.
+ https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-regex-rewrite
+ Some examples:
+ (1) replaceRegexMatch:
+ pattern: ^/service/([^/]+)(/.*)$
+ substitution: \2/instance/\1
+ Would transform /service/foo/v1/api into /v1/api/instance/foo.
+ (2) replaceRegexMatch:
+ pattern: one
+ substitution: two
+ Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/two/zzz.
+ (3) replaceRegexMatch:
+ pattern: ^(.*?)one(.*)$
+ substitution: \1two\2
+ Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/one/zzz.
+ (3) replaceRegexMatch:
+ pattern: (?i)/xxx/
+ substitution: /yyy/
+ Would transform path /aaa/XxX/bbb into /aaa/yyy/bbb (case-insensitive).
+ properties:
+ pattern:
+ description: |-
+ Pattern matches a regular expression against the value of the HTTP Path.The regex string must
+ adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax.
+ minLength: 1
+ type: string
+ substitution:
+ description: |-
+ Substitution is an expression that replaces the matched portion.The expression may include numbered
+ capture groups that adhere to syntax documented in https://github.com/google/re2/wiki/Syntax.
+ type: string
+ required:
+ - pattern
+ - substitution
+ type: object
+ type:
+ description: HTTPPathModifierType defines the type of path
+ redirect or rewrite.
+ enum:
+ - ReplaceRegexMatch
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If HTTPPathModifier type is ReplaceRegexMatch, replaceRegexMatch
+ field needs to be set.
+ rule: 'self.type == ''ReplaceRegexMatch'' ? has(self.replaceRegexMatch)
+ : !has(self.replaceRegexMatch)'
+ type: object
+ type: object
+ required:
+ - spec
+ type: object
+ served: true
+ storage: true
+ subresources: {}
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
index 3906b325b3d..e611a00ce10 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.15.0
+ controller-gen.kubebuilder.io/version: v0.16.1
name: securitypolicies.gateway.envoyproxy.io
spec:
group: gateway.envoyproxy.io
@@ -66,7 +66,6 @@ spec:
These rules are evaluated in order, the first matching rule will be applied,
and the rest will be skipped.
-
For example, if there are two rules: the first rule allows the request
and the second rule denies it, when a request matches both rules, it will be allowed.
items:
@@ -83,17 +82,24 @@ spec:
name:
description: |-
Name is a user-friendly name for the rule.
- If not specified, Envoy Gateway will generate a unique name for the rule.n
+ If not specified, Envoy Gateway will generate a unique name for the rule.
+ maxLength: 253
+ minLength: 1
type: string
principal:
- description: Principal specifies the client identity of
- a request.
+ description: |-
+ Principal specifies the client identity of a request.
+ If there are multiple principal types, all principals must match for the rule to match.
+ For example, if there are two principals: one for client IP and one for JWT claim,
+ the rule will match only if both the client IP and the JWT claim match.
properties:
clientCIDRs:
description: |-
ClientCIDRs are the IP CIDR ranges of the client.
Valid examples are "192.168.1.0/24" or "2001:db8::/64"
+ If multiple CIDR ranges are specified, one of the CIDR ranges must match
+ the client IP for the rule to match.
The client IP is inferred from the X-Forwarded-For header, a custom header,
or the proxy protocol.
@@ -107,9 +113,94 @@ spec:
type: string
minItems: 1
type: array
- required:
- - clientCIDRs
+ jwt:
+ description: |-
+ JWT authorize the request based on the JWT claims and scopes.
+ Note: in order to use JWT claims for authorization, you must configure the
+ JWT authentication in the same `SecurityPolicy`.
+ properties:
+ claims:
+ description: |-
+ Claims are the claims in a JWT token.
+
+ If multiple claims are specified, all claims must match for the rule to match.
+ For example, if there are two claims: one for the audience and one for the issuer,
+ the rule will match only if both the audience and the issuer match.
+ items:
+ description: JWTClaim specifies a claim in a JWT
+ token.
+ properties:
+ name:
+ description: |-
+ Name is the name of the claim.
+ If it is a nested claim, use a dot (.) separated string as the name to
+ represent the full path to the claim.
+ For example, if the claim is in the "department" field in the "organization" field,
+ the name should be "organization.department".
+ maxLength: 253
+ minLength: 1
+ type: string
+ valueType:
+ default: String
+ description: |-
+ ValueType is the type of the claim value.
+ Only String and StringArray types are supported for now.
+ enum:
+ - String
+ - StringArray
+ type: string
+ values:
+ description: |-
+ Values are the values that the claim must match.
+ If the claim is a string type, the specified value must match exactly.
+ If the claim is a string array type, the specified value must match one of the values in the array.
+ If multiple values are specified, one of the values must match for the rule to match.
+ items:
+ type: string
+ maxItems: 16
+ minItems: 1
+ type: array
+ required:
+ - name
+ - values
+ type: object
+ maxItems: 16
+ minItems: 1
+ type: array
+ provider:
+ description: |-
+ Provider is the name of the JWT provider that used to verify the JWT token.
+ In order to use JWT claims for authorization, you must configure the JWT
+ authentication with the same provider in the same `SecurityPolicy`.
+ maxLength: 253
+ minLength: 1
+ type: string
+ scopes:
+ description: |-
+ Scopes are a special type of claim in a JWT token that represents the permissions of the client.
+
+ The value of the scopes field should be a space delimited string that is expected in the scope parameter,
+ as defined in RFC 6749: https://datatracker.ietf.org/doc/html/rfc6749#page-23.
+
+ If multiple scopes are specified, all scopes must match for the rule to match.
+ items:
+ maxLength: 253
+ minLength: 1
+ type: string
+ maxItems: 16
+ minItems: 1
+ type: array
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: at least one of claims or scopes must be
+ specified
+ rule: (has(self.claims) || has(self.scopes))
type: object
+ x-kubernetes-validations:
+ - message: at least one of clientCIDRs or jwt must be specified
+ rule: (has(self.clientCIDRs) || has(self.jwt))
required:
- action
- principal
@@ -126,7 +217,6 @@ spec:
htpasswd format, used to verify user credentials in the "Authorization"
header.
-
This is an Opaque secret. The username-password pairs should be stored in
the key ".htpasswd". As the key name indicates, the value needs to be the
htpasswd format, for example: "user1:{SHA}hashed_user1_password".
@@ -134,7 +224,6 @@ spec:
Reference to https://httpd.apache.org/docs/2.4/programs/htpasswd.html
for more details.
-
Note: The secret must be in the same namespace as the SecurityPolicy.
properties:
group:
@@ -162,13 +251,11 @@ spec:
Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -188,23 +275,29 @@ spec:
description: |-
AllowCredentials indicates whether a request can include user credentials
like cookies, authentication headers, or TLS client certificates.
+ It specifies the value in the Access-Control-Allow-Credentials CORS response header.
type: boolean
allowHeaders:
- description: AllowHeaders defines the headers that are allowed
- to be sent with requests.
+ description: |-
+ AllowHeaders defines the headers that are allowed to be sent with requests.
+ It specifies the allowed headers in the Access-Control-Allow-Headers CORS response header..
+ The value "*" allows any header to be sent.
items:
type: string
type: array
allowMethods:
- description: AllowMethods defines the methods that are allowed
- to make requests.
+ description: |-
+ AllowMethods defines the methods that are allowed to make requests.
+ It specifies the allowed methods in the Access-Control-Allow-Methods CORS response header..
+ The value "*" allows any method to be used.
items:
type: string
- minItems: 1
type: array
allowOrigins:
- description: AllowOrigins defines the origins that are allowed
- to make requests.
+ description: |-
+ AllowOrigins defines the origins that are allowed to make requests.
+ It specifies the allowed origins in the Access-Control-Allow-Origin CORS response header.
+ The value "*" allows any origin to make requests.
items:
description: |-
Origin is defined by the scheme (protocol), hostname (domain), and port of
@@ -214,7 +307,6 @@ spec:
In addition to that a single wildcard (with or without scheme) can be
configured to match any origin.
-
For example, the following are valid origins:
- https://foo.example.com
- https://*.example.com
@@ -225,22 +317,40 @@ spec:
minLength: 1
pattern: ^(\*|https?:\/\/(\*|(\*\.)?(([\w-]+\.?)+)?[\w-]+)(:\d{1,5})?)$
type: string
- minItems: 1
type: array
exposeHeaders:
- description: ExposeHeaders defines the headers that can be exposed
- in the responses.
+ description: |-
+ ExposeHeaders defines which response headers should be made accessible to
+ scripts running in the browser.
+ It specifies the headers in the Access-Control-Expose-Headers CORS response header..
+ The value "*" allows any header to be exposed.
items:
type: string
type: array
maxAge:
- description: MaxAge defines how long the results of a preflight
- request can be cached.
+ description: |-
+ MaxAge defines how long the results of a preflight request can be cached.
+ It specifies the value in the Access-Control-Max-Age CORS response header..
type: string
type: object
extAuth:
description: ExtAuth defines the configuration for External Authorization.
properties:
+ bodyToExtAuth:
+ description: BodyToExtAuth defines the Body to Ext Auth configuration.
+ properties:
+ maxRequestBytes:
+ description: |-
+ MaxRequestBytes is the maximum size of a message body that the filter will hold in memory.
+ Envoy will return HTTP 413 and will not initiate the authorization process when buffer
+ reaches the number set in this field.
+ Note that this setting will have precedence over failOpen mode.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - maxRequestBytes
+ type: object
failOpen:
default: false
description: |-
@@ -260,8 +370,6 @@ spec:
description: |-
BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
- Only Service kind is supported for now.
-
Deprecated: Use BackendRefs instead.
properties:
@@ -279,20 +387,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -308,13 +412,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -342,11 +444,19 @@ spec:
description: |-
BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
- Only Service kind is supported for now.
items:
description: BackendRef defines how an ObjectReference that
is specific to BackendRef.
properties:
+ fallback:
+ description: |-
+ Fallback indicates whether the backend is designated as a fallback.
+ Multiple fallback backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -361,20 +471,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -390,13 +496,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -420,17 +524,708 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
- maxItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: only support Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core group.
- rule: self.all(f, f.group == '')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections that
+ Envoy will establish to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel requests
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel retries
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending requests
+ that Envoy will queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform active
+ health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines the number
+ of healthy health checks required before a backend
+ host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines a list
+ of HTTP expected responses to match.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines the http
+ status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP path that
+ will be requested during health checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ active health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the expected
+ response payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ send:
+ description: Send defines the request payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time to wait
+ for a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines the number
+ of unhealthy health checks required before a
+ backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP, http field
+ needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http) :
+ !has(self.http)'
+ - message: If Health Checker type is TCP, tcp field
+ needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)'
+ - message: The grpc field can only be set if the Health
+ Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC'' :
+ true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines the base
+ duration for which a host will be ejected on
+ consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets the number
+ of consecutive 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors sets the
+ number of consecutive gateway errors triggering
+ ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ passive health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets the maximum
+ percentage of hosts in a cluster that can be
+ ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors enables
+ splitting of errors between external and local
+ origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration for backend
+ connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie hash
+ policy when the consistent hash type is set
+ to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes to set
+ for the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header hash
+ policy when the consistent hash type is set
+ to Header.
+ properties:
+ name:
+ description: Name of the header to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent hashing,
+ must be prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header, the
+ header field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie, the
+ cookie field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash, consistentHash
+ field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported for RoundRobin
+ and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy Protocol
+ when communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ retry:
+ description: |-
+ Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
+ If not set, retry will be disabled.
+ properties:
+ numRetries:
+ default: 2
+ description: NumRetries is the number of retries to
+ be attempted. Defaults to 2.
+ format: int32
+ minimum: 0
+ type: integer
+ perRetry:
+ description: PerRetry is the retry policy to be applied
+ per retry attempt.
+ properties:
+ backOff:
+ description: |-
+ Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
+ back-off algorithm for retries. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries
+ properties:
+ baseInterval:
+ description: BaseInterval is the base interval
+ between retries.
+ format: duration
+ type: string
+ maxInterval:
+ description: |-
+ MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
+ The default is 10 times the base_interval
+ format: duration
+ type: string
+ type: object
+ timeout:
+ description: Timeout is the timeout per retry
+ attempt.
+ format: duration
+ type: string
+ type: object
+ retryOn:
+ description: |-
+ RetryOn specifies the retry trigger condition.
+
+ If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503).
+ properties:
+ httpStatusCodes:
+ description: |-
+ HttpStatusCodes specifies the http status codes to be retried.
+ The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
+ items:
+ description: HTTPStatus defines the http status
+ code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ triggers:
+ description: Triggers specifies the retry trigger
+ condition(Http/Grpc).
+ items:
+ description: TriggerEnum specifies the conditions
+ that trigger retries.
+ enum:
+ - 5xx
+ - gateway-error
+ - reset
+ - connect-failure
+ - retriable-4xx
+ - refused-stream
+ - retriable-status-codes
+ - cancelled
+ - deadline-exceeded
+ - internal
+ - resource-exhausted
+ - unavailable
+ type: string
+ type: array
+ type: object
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ requestTimeout:
+ description: RequestTimeout is the time until
+ which entire response is received from the upstream.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
type: object
x-kubernetes-validations:
- message: backendRef or backendRefs needs to be set
rule: has(self.backendRef) || self.backendRefs.size() > 0
+ - message: BackendRefs only supports Service and Backend kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind
+ == ''Service'' || f.kind == ''Backend'') : true'
+ - message: BackendRefs only supports Core and gateway.envoyproxy.io
+ group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group
+ == "" || f.group == ''gateway.envoyproxy.io'')) : true'
headersToExtAuth:
description: |-
HeadersToExtAuth defines the client request headers that will be included
@@ -456,8 +1251,6 @@ spec:
description: |-
BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
- Only Service kind is supported for now.
-
Deprecated: Use BackendRefs instead.
properties:
@@ -475,20 +1268,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -504,13 +1293,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -538,11 +1325,19 @@ spec:
description: |-
BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
- Only Service kind is supported for now.
items:
description: BackendRef defines how an ObjectReference that
is specific to BackendRef.
properties:
+ fallback:
+ description: |-
+ Fallback indicates whether the backend is designated as a fallback.
+ Multiple fallback backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -557,20 +1352,16 @@ spec:
Kind is the Kubernetes resource kind of the referent. For example
"Service".
-
Defaults to "Service" when not specified.
-
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.
-
Support: Core (Services with a type other than ExternalName)
-
Support: Implementation-specific (Services with type ExternalName)
maxLength: 63
minLength: 1
@@ -586,13 +1377,11 @@ spec:
Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -616,13 +1405,697 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
- maxItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: only support Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core group.
- rule: self.all(f, f.group == '')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections that
+ Envoy will establish to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel requests
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel retries
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending requests
+ that Envoy will queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform active
+ health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines the number
+ of healthy health checks required before a backend
+ host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines a list
+ of HTTP expected responses to match.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines the http
+ status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP path that
+ will be requested during health checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ active health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the expected
+ response payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ send:
+ description: Send defines the request payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time to wait
+ for a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines the number
+ of unhealthy health checks required before a
+ backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP, http field
+ needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http) :
+ !has(self.http)'
+ - message: If Health Checker type is TCP, tcp field
+ needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)'
+ - message: The grpc field can only be set if the Health
+ Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC'' :
+ true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines the base
+ duration for which a host will be ejected on
+ consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets the number
+ of consecutive 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors sets the
+ number of consecutive gateway errors triggering
+ ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ passive health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets the maximum
+ percentage of hosts in a cluster that can be
+ ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors enables
+ splitting of errors between external and local
+ origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration for backend
+ connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie hash
+ policy when the consistent hash type is set
+ to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes to set
+ for the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header hash
+ policy when the consistent hash type is set
+ to Header.
+ properties:
+ name:
+ description: Name of the header to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent hashing,
+ must be prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header, the
+ header field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie, the
+ cookie field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash, consistentHash
+ field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported for RoundRobin
+ and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy Protocol
+ when communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ retry:
+ description: |-
+ Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
+ If not set, retry will be disabled.
+ properties:
+ numRetries:
+ default: 2
+ description: NumRetries is the number of retries to
+ be attempted. Defaults to 2.
+ format: int32
+ minimum: 0
+ type: integer
+ perRetry:
+ description: PerRetry is the retry policy to be applied
+ per retry attempt.
+ properties:
+ backOff:
+ description: |-
+ Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
+ back-off algorithm for retries. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries
+ properties:
+ baseInterval:
+ description: BaseInterval is the base interval
+ between retries.
+ format: duration
+ type: string
+ maxInterval:
+ description: |-
+ MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
+ The default is 10 times the base_interval
+ format: duration
+ type: string
+ type: object
+ timeout:
+ description: Timeout is the timeout per retry
+ attempt.
+ format: duration
+ type: string
+ type: object
+ retryOn:
+ description: |-
+ RetryOn specifies the retry trigger condition.
+
+ If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503).
+ properties:
+ httpStatusCodes:
+ description: |-
+ HttpStatusCodes specifies the http status codes to be retried.
+ The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
+ items:
+ description: HTTPStatus defines the http status
+ code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ triggers:
+ description: Triggers specifies the retry trigger
+ condition(Http/Grpc).
+ items:
+ description: TriggerEnum specifies the conditions
+ that trigger retries.
+ enum:
+ - 5xx
+ - gateway-error
+ - reset
+ - connect-failure
+ - retriable-4xx
+ - refused-stream
+ - retriable-status-codes
+ - cancelled
+ - deadline-exceeded
+ - internal
+ - resource-exhausted
+ - unavailable
+ type: string
+ type: array
+ type: object
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ requestTimeout:
+ description: RequestTimeout is the time until
+ which entire response is received from the upstream.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
headersToBackend:
description: |-
HeadersToBackend are the authorization response headers that will be added
@@ -643,6 +2116,20 @@ spec:
x-kubernetes-validations:
- message: backendRef or backendRefs needs to be set
rule: has(self.backendRef) || self.backendRefs.size() > 0
+ - message: BackendRefs only supports Service and Backend kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind
+ == ''Service'' || f.kind == ''Backend'') : true'
+ - message: BackendRefs only supports Core and gateway.envoyproxy.io
+ group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group
+ == "" || f.group == ''gateway.envoyproxy.io'')) : true'
+ recomputeRoute:
+ description: |-
+ RecomputeRoute clears the route cache and recalculates the routing decision.
+ This field must be enabled if the headers added or modified by the ExtAuth are used for
+ route matching decisions. If the recomputation selects a new route, features targeting
+ the new matched route will be applied.
+ type: boolean
type: object
x-kubernetes-validations:
- message: one of grpc or http must be specified
@@ -650,24 +2137,6 @@ spec:
- message: only one of grpc or http can be specified
rule: (has(self.grpc) && !has(self.http)) || (!has(self.grpc) &&
has(self.http))
- - message: group is invalid, only the core API group (specified by
- omitting the group field or setting it to an empty string) is
- supported
- rule: 'has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.group)
- || self.grpc.backendRef.group == "") : true'
- - message: kind is invalid, only Service (specified by omitting the
- kind field or setting it to 'Service') is supported
- rule: 'has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.kind)
- || self.grpc.backendRef.kind == ''Service'') : true'
- - message: group is invalid, only the core API group (specified by
- omitting the group field or setting it to an empty string) is
- supported
- rule: 'has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.group)
- || self.http.backendRef.group == "") : true'
- - message: kind is invalid, only Service (specified by omitting the
- kind field or setting it to 'Service') is supported
- rule: 'has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.kind)
- || self.http.backendRef.kind == ''Service'') : true'
jwt:
description: JWT defines the configuration for JSON Web Token (JWT)
authentication.
@@ -827,7 +2296,6 @@ spec:
The Kubernetes secret which contains the OIDC client secret to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
-
This is an Opaque secret. The client secret should be stored in the key
"client-secret".
properties:
@@ -856,13 +2324,11 @@ spec:
Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.
-
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.
-
Support: Core
maxLength: 63
minLength: 1
@@ -871,6 +2337,14 @@ spec:
required:
- name
type: object
+ cookieDomain:
+ description: |-
+ The optional domain to set the access and ID token cookies on.
+ If not set, the cookies will default to the host of the request, not including the subdomains.
+ If set, the cookies will be set on the specified domain and all subdomains.
+ This means that requests to any subdomain will not require reauthentication after users log in to the parent domain.
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9]))*$
+ type: string
cookieNames:
description: |-
The optional cookie name overrides to be used for Bearer and IdToken cookies in the
@@ -896,7 +2370,6 @@ spec:
This field is only used when the exp (expiration time) claim is omitted in
the refresh token or the refresh token is not JWT.
-
If not specified, defaults to 604800s (one week).
Note: this field is only applicable when the "refreshToken" field is set to true.
type: string
@@ -907,7 +2380,6 @@ spec:
of the authorization server if it is provided. This field is only used when
the expiry time is not provided by the authorization.
-
If not specified, defaults to 0. In this case, the "expires_in" field in
the authorization response must be set by the authorization server, or the
OAuth flow will fail.
@@ -922,7 +2394,6 @@ spec:
description: |-
The path to log a user out, clearing their credential cookies.
-
If not specified, uses a default logout path "/logout"
type: string
provider:
@@ -933,7 +2404,856 @@ spec:
The OIDC Provider's [authorization endpoint](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint).
If not provided, EG will try to discover it from the provider's [Well-Known Configuration Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse).
type: string
- issuer:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+ Defaults to "Service" when not specified.
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+ Support: Core (Services with a type other than ExternalName)
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind == ''Service'')
+ ? has(self.port) : true'
+ backendRefs:
+ description: |-
+ BackendRefs references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+ items:
+ description: BackendRef defines how an ObjectReference that
+ is specific to BackendRef.
+ properties:
+ fallback:
+ description: |-
+ Fallback indicates whether the backend is designated as a fallback.
+ Multiple fallback backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+ Defaults to "Service" when not specified.
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+ Support: Core (Services with a type other than ExternalName)
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind == ''Service'')
+ ? has(self.port) : true'
+ maxItems: 16
+ type: array
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections that
+ Envoy will establish to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel requests
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel retries
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending requests
+ that Envoy will queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform active
+ health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines the number
+ of healthy health checks required before a backend
+ host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines a list
+ of HTTP expected responses to match.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines the http
+ status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP path that
+ will be requested during health checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ active health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the expected
+ response payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ send:
+ description: Send defines the request payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time to wait
+ for a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines the number
+ of unhealthy health checks required before a
+ backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP, http field
+ needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http) :
+ !has(self.http)'
+ - message: If Health Checker type is TCP, tcp field
+ needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)'
+ - message: The grpc field can only be set if the Health
+ Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC'' :
+ true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines the base
+ duration for which a host will be ejected on
+ consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets the number
+ of consecutive 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors sets the
+ number of consecutive gateway errors triggering
+ ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ passive health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets the maximum
+ percentage of hosts in a cluster that can be
+ ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors enables
+ splitting of errors between external and local
+ origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration for backend
+ connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie hash
+ policy when the consistent hash type is set
+ to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes to set
+ for the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header hash
+ policy when the consistent hash type is set
+ to Header.
+ properties:
+ name:
+ description: Name of the header to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent hashing,
+ must be prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header, the
+ header field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie, the
+ cookie field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash, consistentHash
+ field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported for RoundRobin
+ and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy Protocol
+ when communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ retry:
+ description: |-
+ Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
+ If not set, retry will be disabled.
+ properties:
+ numRetries:
+ default: 2
+ description: NumRetries is the number of retries to
+ be attempted. Defaults to 2.
+ format: int32
+ minimum: 0
+ type: integer
+ perRetry:
+ description: PerRetry is the retry policy to be applied
+ per retry attempt.
+ properties:
+ backOff:
+ description: |-
+ Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
+ back-off algorithm for retries. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries
+ properties:
+ baseInterval:
+ description: BaseInterval is the base interval
+ between retries.
+ format: duration
+ type: string
+ maxInterval:
+ description: |-
+ MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
+ The default is 10 times the base_interval
+ format: duration
+ type: string
+ type: object
+ timeout:
+ description: Timeout is the timeout per retry
+ attempt.
+ format: duration
+ type: string
+ type: object
+ retryOn:
+ description: |-
+ RetryOn specifies the retry trigger condition.
+
+ If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503).
+ properties:
+ httpStatusCodes:
+ description: |-
+ HttpStatusCodes specifies the http status codes to be retried.
+ The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
+ items:
+ description: HTTPStatus defines the http status
+ code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ triggers:
+ description: Triggers specifies the retry trigger
+ condition(Http/Grpc).
+ items:
+ description: TriggerEnum specifies the conditions
+ that trigger retries.
+ enum:
+ - 5xx
+ - gateway-error
+ - reset
+ - connect-failure
+ - retriable-4xx
+ - refused-stream
+ - retriable-status-codes
+ - cancelled
+ - deadline-exceeded
+ - internal
+ - resource-exhausted
+ - unavailable
+ type: string
+ type: array
+ type: object
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ requestTimeout:
+ description: RequestTimeout is the time until
+ which entire response is received from the upstream.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
+ issuer:
description: |-
The OIDC Provider's [issuer identifier](https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery).
Issuer MUST be a URI RFC 3986 [RFC3986] with a scheme component that MUST
@@ -949,6 +3269,15 @@ spec:
required:
- issuer
type: object
+ x-kubernetes-validations:
+ - message: BackendRefs must be used, backendRef is not supported.
+ rule: '!has(self.backendRef)'
+ - message: Retry timeout is not supported.
+ rule: has(self.backendSettings)? (has(self.backendSettings.retry)?(has(self.backendSettings.retry.perRetry)?
+ !has(self.backendSettings.retry.perRetry.timeout):true):true):true
+ - message: HTTPStatusCodes is not supported.
+ rule: has(self.backendSettings)? (has(self.backendSettings.retry)?(has(self.backendSettings.retry.retryOn)?
+ !has(self.backendSettings.retry.retryOn.httpStatusCodes):true):true):true
redirectURL:
description: |-
The redirect URL to be used in the OIDC
@@ -962,7 +3291,6 @@ spec:
When set to true, the Envoy will use the refresh token to get a new id token
and access token when they expire.
-
If not specified, defaults to false.
type: boolean
resources:
@@ -992,7 +3320,6 @@ spec:
This policy and the TargetRef MUST be in the same namespace for this
Policy to have effect
-
Deprecated: use targetRefs/targetSelectors instead
properties:
group:
@@ -1017,12 +3344,10 @@ spec:
unspecified, this targetRef targets the entire resource. In the following
resources, SectionName is interpreted as the following:
-
* Gateway: Listener name
* HTTPRoute: HTTPRouteRule name
* Service: Port name
-
If a SectionName is specified, but does not exist on the targeted object,
the Policy must fail to attach, and the policy implementation should record
a `ResolvedRefs` or similar Condition in the Policy's status.
@@ -1047,7 +3372,6 @@ spec:
mode works, and a sample Policy resource, refer to the policy attachment
documentation for Gateway API.
-
Note: This should only be used for direct policy attachment when references
to SectionName are actually needed. In all other cases,
LocalPolicyTargetReference should be used.
@@ -1074,12 +3398,10 @@ spec:
unspecified, this targetRef targets the entire resource. In the following
resources, SectionName is interpreted as the following:
-
* Gateway: Listener name
* HTTPRoute: HTTPRouteRule name
* Service: Port name
-
If a SectionName is specified, but does not exist on the targeted object,
the Policy must fail to attach, and the policy implementation should record
a `ResolvedRefs` or similar Condition in the Policy's status.
@@ -1149,6 +3471,10 @@ spec:
- message: this policy does not yet support the sectionName field
rule: 'has(self.targetRefs) ? self.targetRefs.all(ref, !has(ref.sectionName))
: true'
+ - message: if authorization.rules.principal.jwt is used, jwt must be defined
+ rule: '(has(self.authorization) && has(self.authorization.rules) &&
+ self.authorization.rules.exists(r, has(r.principal.jwt))) ? has(self.jwt)
+ : true'
status:
description: Status defines the current status of SecurityPolicy.
properties:
@@ -1161,27 +3487,22 @@ spec:
the controller first sees the policy and SHOULD update the entry as
appropriate when the relevant ancestor is modified.
-
Note that choosing the relevant ancestor is left to the Policy designers;
an important part of Policy design is designing the right object level at
which to namespace this status.
-
Note also that implementations MUST ONLY populate ancestor status for
the Ancestor resources they are responsible for. Implementations MUST
use the ControllerName field to uniquely identify the entries in this list
that they are responsible for.
-
Note that to achieve this, the list of PolicyAncestorStatus structs
MUST be treated as a map with a composite key, made up of the AncestorRef
and ControllerName fields combined.
-
A maximum of 16 ancestors will be represented in this list. An empty list
means the Policy is not relevant for any ancestors.
-
If this slice is full, implementations MUST NOT add further entries.
Instead they MUST consider the policy unimplementable and signal that
on any related resources such as the ancestor that would be referenced
@@ -1193,7 +3514,6 @@ spec:
PolicyAncestorStatus describes the status of a route with respect to an
associated Ancestor.
-
Ancestors refer to objects that are either the Target of a policy or above it
in terms of object hierarchy. For example, if a policy targets a Service, the
Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
@@ -1202,28 +3522,23 @@ spec:
SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
have a _very_ good reason otherwise.
-
In the context of policy attachment, the Ancestor is used to distinguish which
resource results in a distinct application of this policy. For example, if a policy
targets a Service, it may have a distinct result per attached Gateway.
-
Policies targeting the same resource may have different effects depending on the
ancestors of those resources. For example, different Gateways targeting the same
Service may have different capabilities, especially if they have different underlying
implementations.
-
For example, in BackendTLSPolicy, the Policy attaches to a Service that is
used as a backend in a HTTPRoute that is itself attached to a Gateway.
In this case, the relevant object for status is the Gateway, and that is the
ancestor object referred to in this status.
-
Note that a parent is also an ancestor, so for objects where the parent is the
relevant object for status, this struct SHOULD still be used.
-
This struct is intended to be used in a slice that's effectively a map,
with a composite key made up of the AncestorRef and the ControllerName.
properties:
@@ -1240,7 +3555,6 @@ spec:
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
-
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -1250,14 +3564,11 @@ spec:
description: |-
Kind is kind of the referent.
-
There are two kinds of parent resources with "Core" support:
-
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
-
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
@@ -1267,7 +3578,6 @@ spec:
description: |-
Name is the name of the referent.
-
Support: Core
maxLength: 253
minLength: 1
@@ -1277,20 +3587,17 @@ spec:
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
-
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
Gateway has the AllowedRoutes field, and ReferenceGrant provides a
generic way to enable any other kind of cross-namespace reference.
-
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
-
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
@@ -1298,7 +3605,6 @@ spec:
ParentRef of the Route.
-
Support: Core
maxLength: 63
minLength: 1
@@ -1309,7 +3615,6 @@ spec:
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
-
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
@@ -1318,19 +3623,16 @@ spec:
and SectionName are specified, the name and port of the selected listener
must match both specified values.
-
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
-
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
-
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
@@ -1339,7 +3641,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
-
Support: Extended
format: int32
maximum: 65535
@@ -1350,7 +3651,6 @@ spec:
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
-
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
@@ -1358,12 +3658,10 @@ spec:
are specified, the name and port of the selected listener must match
both specified values.
-
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
-
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
@@ -1373,7 +3671,6 @@ spec:
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
-
Support: Core
maxLength: 253
minLength: 1
@@ -1386,18 +3683,8 @@ spec:
description: Conditions describes the status of the Policy with
respect to the given Ancestor.
items:
- description: "Condition contains details for one aspect of
- the current state of this API Resource.\n---\nThis struct
- is intended for direct use as an array at the field path
- .status.conditions. For example,\n\n\n\ttype FooStatus
- struct{\n\t // Represents the observations of a foo's
- current state.\n\t // Known .status.conditions.type are:
- \"Available\", \"Progressing\", and \"Degraded\"\n\t //
- +patchMergeKey=type\n\t // +patchStrategy=merge\n\t //
- +listType=map\n\t // +listMapKey=type\n\t Conditions
- []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\"
- patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
- \ // other fields\n\t}"
+ description: Condition contains details for one aspect of
+ the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
@@ -1439,12 +3726,7 @@ spec:
- Unknown
type: string
type:
- description: |-
- type of condition in CamelCase or in foo.example.com/CamelCase.
- ---
- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
- useful (see .node.status.conditions), the ability to deconflict is important.
- The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@@ -1467,15 +3749,12 @@ spec:
controller that wrote this status. This corresponds with the
controllerName field on GatewayClass.
-
Example: "example.net/gateway-controller".
-
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
valid Kubernetes names
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-
Controllers MUST populate this field when writing status. Controllers should ensure that
entries to status populated with their ControllerName are cleaned up when they are no
longer necessary.
diff --git a/charts/gateway-helm/templates/_rbac.tpl b/charts/gateway-helm/templates/_rbac.tpl
index fb9304e7d89..52a5648818c 100644
--- a/charts/gateway-helm/templates/_rbac.tpl
+++ b/charts/gateway-helm/templates/_rbac.tpl
@@ -43,6 +43,7 @@ apiGroups:
- apps
resources:
- deployments
+- daemonsets
verbs:
- get
- list
@@ -71,6 +72,7 @@ resources:
- securitypolicies
- envoyextensionpolicies
- backends
+- httproutefilters
verbs:
- get
- list
diff --git a/charts/gateway-helm/templates/certgen.yaml b/charts/gateway-helm/templates/certgen.yaml
index f122f0a8e49..f98c414ba22 100644
--- a/charts/gateway-helm/templates/certgen.yaml
+++ b/charts/gateway-helm/templates/certgen.yaml
@@ -38,12 +38,22 @@ spec:
resources:
{{- toYaml . | nindent 10 }}
{{- end }}
+ securityContext:
+ {{- toYaml .Values.certgen.job.securityContext | nindent 10 }}
{{- include "eg.image.pullSecrets" . | nindent 6 }}
+ {{- with .Values.certgen.job.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.certgen.job.nodeSelector }}
+ nodeSelector:
+ {{ toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.certgen.job.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 6 }}
+ {{- end }}
restartPolicy: Never
- securityContext:
- runAsGroup: 65534
- runAsNonRoot: true
- runAsUser: 65534
serviceAccountName: {{ include "eg.fullname" . }}-certgen
{{- if not ( kindIs "invalid" .Values.certgen.job.ttlSecondsAfterFinished) }}
ttlSecondsAfterFinished: {{ .Values.certgen.job.ttlSecondsAfterFinished }}
diff --git a/charts/gateway-helm/templates/envoy-gateway-deployment.yaml b/charts/gateway-helm/templates/envoy-gateway-deployment.yaml
index 597063e2852..7746dd2e4ac 100644
--- a/charts/gateway-helm/templates/envoy-gateway-deployment.yaml
+++ b/charts/gateway-helm/templates/envoy-gateway-deployment.yaml
@@ -1,25 +1,3 @@
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: envoy-gateway
- namespace: '{{ .Release.Namespace }}'
- labels:
- {{- include "eg.labels" . | nindent 4 }}
----
-{{- if and .Values.podDisruptionBudget.minAvailable (ge (int .Values.podDisruptionBudget.minAvailable) 1) }}
-apiVersion: policy/v1
-kind: PodDisruptionBudget
-metadata:
- name: envoy-gateway
- namespace: '{{ .Release.Namespace }}'
-spec:
- minAvailable: {{ .Values.podDisruptionBudget.minAvailable }}
- selector:
- matchLabels:
- control-plane: envoy-gateway
- {{- include "eg.selectorLabels" . | nindent 6 }}
----
-{{- end }}
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -51,6 +29,10 @@ spec:
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
+ {{- with .Values.deployment.pod.nodeSelector }}
+ nodeSelector:
+ {{ toYaml . | nindent 8 }}
+ {{- end }}
{{- with .Values.deployment.pod.topologySpreadConstraints }}
topologySpreadConstraints:
{{- toYaml . | nindent 6 }}
@@ -91,10 +73,10 @@ spec:
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
- resources: {{- toYaml .Values.deployment.envoyGateway.resources | nindent 10
- }}
+ resources:
+ {{- toYaml .Values.deployment.envoyGateway.resources | nindent 10 }}
securityContext:
- allowPrivilegeEscalation: false
+ {{- toYaml .Values.deployment.envoyGateway.securityContext | nindent 10 }}
volumeMounts:
- mountPath: /config
name: envoy-gateway-config
@@ -103,8 +85,9 @@ spec:
name: certs
readOnly: true
{{- include "eg.image.pullSecrets" . | nindent 6 }}
- securityContext:
- runAsNonRoot: true
+ {{- with .Values.deployment.priorityClassName }}
+ priorityClassName: {{ . | quote }}
+ {{- end }}
serviceAccountName: envoy-gateway
terminationGracePeriodSeconds: 10
volumes:
diff --git a/charts/gateway-helm/templates/envoy-gateway-poddisruptionbudget.yaml b/charts/gateway-helm/templates/envoy-gateway-poddisruptionbudget.yaml
new file mode 100644
index 00000000000..8e0bca0f1d8
--- /dev/null
+++ b/charts/gateway-helm/templates/envoy-gateway-poddisruptionbudget.yaml
@@ -0,0 +1,18 @@
+{{- if or (and .Values.podDisruptionBudget.minAvailable (ge (int .Values.podDisruptionBudget.minAvailable) 1) ) (and .Values.podDisruptionBudget.maxUnavailable (ge (int .Values.podDisruptionBudget.maxUnavailable) 1) )}}
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: envoy-gateway
+ namespace: '{{ .Release.Namespace }}'
+spec:
+ {{- if and .Values.podDisruptionBudget.minAvailable }}
+ minAvailable: {{ .Values.podDisruptionBudget.minAvailable }}
+ {{- end }}
+ {{- if .Values.podDisruptionBudget.maxUnavailable }}
+ maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
+ {{- end }}
+ selector:
+ matchLabels:
+ control-plane: envoy-gateway
+ {{- include "eg.selectorLabels" . | nindent 6 }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/gateway-helm/templates/envoy-gateway-service.yaml b/charts/gateway-helm/templates/envoy-gateway-service.yaml
index 099129477f7..39b30ea6710 100644
--- a/charts/gateway-helm/templates/envoy-gateway-service.yaml
+++ b/charts/gateway-helm/templates/envoy-gateway-service.yaml
@@ -3,6 +3,10 @@ kind: Service
metadata:
name: envoy-gateway
namespace: '{{ .Release.Namespace }}'
+ {{- with .Values.service.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
labels:
control-plane: envoy-gateway
{{- include "eg.labels" . | nindent 4 }}
diff --git a/charts/gateway-helm/templates/envoy-gateway-serviceaccount.yaml b/charts/gateway-helm/templates/envoy-gateway-serviceaccount.yaml
new file mode 100644
index 00000000000..23af6fee1f1
--- /dev/null
+++ b/charts/gateway-helm/templates/envoy-gateway-serviceaccount.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: envoy-gateway
+ namespace: '{{ .Release.Namespace }}'
+ labels:
+ {{- include "eg.labels" . | nindent 4 }}
diff --git a/charts/gateway-helm/templates/infra-manager-rbac.yaml b/charts/gateway-helm/templates/infra-manager-rbac.yaml
index 02382bc271c..74c0ec6282e 100644
--- a/charts/gateway-helm/templates/infra-manager-rbac.yaml
+++ b/charts/gateway-helm/templates/infra-manager-rbac.yaml
@@ -11,10 +11,12 @@ rules:
resources:
- serviceaccounts
- services
+ - configmaps
verbs:
- create
- get
- delete
+ - deletecollection
- patch
- apiGroups:
- apps
@@ -25,6 +27,7 @@ rules:
- create
- get
- delete
+ - deletecollection
- patch
- apiGroups:
- autoscaling
@@ -36,6 +39,7 @@ rules:
- create
- get
- delete
+ - deletecollection
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
diff --git a/charts/gateway-helm/values.tmpl.yaml b/charts/gateway-helm/values.tmpl.yaml
index 9240c4c2c13..cfcd9532491 100644
--- a/charts/gateway-helm/values.tmpl.yaml
+++ b/charts/gateway-helm/values.tmpl.yaml
@@ -20,6 +20,8 @@ global:
pullSecrets: []
podDisruptionBudget:
minAvailable: 0
+ # maxUnavailable: 1
+
deployment:
envoyGateway:
image:
@@ -29,11 +31,21 @@ deployment:
imagePullSecrets: []
resources:
limits:
- cpu: 500m
memory: 1024Mi
requests:
cpu: 100m
memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsNonRoot: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
ports:
- name: grpc
port: 18000
@@ -47,6 +59,7 @@ deployment:
- name: metrics
port: 19001
targetPort: 19001
+ priorityClassName: null
replicas: 1
pod:
affinity: {}
@@ -56,6 +69,10 @@ deployment:
labels: {}
topologySpreadConstraints: []
tolerations: []
+ nodeSelector: {}
+
+service:
+ annotations: {}
config:
envoyGateway:
@@ -76,7 +93,22 @@ certgen:
job:
annotations: {}
resources: {}
+ affinity: {}
+ tolerations: []
+ nodeSelector: {}
ttlSecondsAfterFinished: 30
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ runAsGroup: 65534
+ runAsUser: 65534
+ seccompProfile:
+ type: RuntimeDefault
rbac:
annotations: {}
labels: {}
diff --git a/embed.go b/embed.go
new file mode 100644
index 00000000000..97f2e3bf547
--- /dev/null
+++ b/embed.go
@@ -0,0 +1,52 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package envoygateway
+
+import (
+ "bytes"
+ _ "embed"
+)
+
+var (
+ //go:embed charts/gateway-helm/crds/gatewayapi-crds.yaml
+ gatewayAPICRDs []byte
+
+ //go:embed charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml
+ backendCRD []byte
+
+ //go:embed charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
+ backendTrafficPolicyCRD []byte
+
+ //go:embed charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
+ clientTrafficPolicyCRD []byte
+
+ //go:embed charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
+ envoyExtensionPolicyCRD []byte
+
+ //go:embed charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml
+ envoyPatchPolicyCRD []byte
+
+ //go:embed charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
+ envoyProxyCRD []byte
+
+ //go:embed charts/gateway-helm/crds/generated/gateway.envoyproxy.io_httproutefilters.yaml
+ httpRouteFilterCRD []byte
+
+ //go:embed charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
+ securityPolicyCRD []byte
+)
+
+var GatewayCRDs = bytes.Join([][]byte{
+ gatewayAPICRDs,
+ backendCRD,
+ backendTrafficPolicyCRD,
+ clientTrafficPolicyCRD,
+ envoyExtensionPolicyCRD,
+ envoyPatchPolicyCRD,
+ envoyProxyCRD,
+ httpRouteFilterCRD,
+ securityPolicyCRD,
+}, []byte(""))
diff --git a/examples/envoy-als/Dockerfile b/examples/envoy-als/Dockerfile
new file mode 100644
index 00000000000..835a8200716
--- /dev/null
+++ b/examples/envoy-als/Dockerfile
@@ -0,0 +1,23 @@
+FROM golang:1.23.3 AS builder
+
+ARG GO_LDFLAGS=""
+
+WORKDIR /workspace
+COPY go.mod go.sum ./
+RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
+ go mod download
+
+COPY . ./
+RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
+ CGO_ENABLED=0 \
+ GOOS=${TARGETOS} \
+ GOARCH=${TARGETARCH} \
+ go build -o /bin/envoy-als -ldflags "${GO_LDFLAGS}" .
+
+# Make our production image
+FROM gcr.io/distroless/static-debian11:nonroot
+COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
+COPY --from=builder /bin/envoy-als /
+
+USER nonroot:nonroot
+ENTRYPOINT ["/envoy-als"]
diff --git a/examples/envoy-als/Makefile b/examples/envoy-als/Makefile
new file mode 100644
index 00000000000..a8ca6cec25d
--- /dev/null
+++ b/examples/envoy-als/Makefile
@@ -0,0 +1,8 @@
+
+IMAGE_PREFIX ?= envoyproxy/gateway-
+APP_NAME ?= envoy-als
+TAG ?= latest
+
+.PHONY: docker-buildx
+docker-buildx:
+ docker buildx build . -t $(IMAGE_PREFIX)$(APP_NAME):$(TAG) --build-arg GO_LDFLAGS="$(GO_LDFLAGS)" --load
diff --git a/examples/envoy-als/go.mod b/examples/envoy-als/go.mod
new file mode 100644
index 00000000000..df62679506a
--- /dev/null
+++ b/examples/envoy-als/go.mod
@@ -0,0 +1,27 @@
+module github.com/envoyproxy/gateway-envoy-als
+
+go 1.23.3
+
+require (
+ github.com/envoyproxy/go-control-plane v0.13.1
+ github.com/prometheus/client_golang v1.20.5
+ google.golang.org/grpc v1.67.1
+)
+
+require (
+ github.com/beorn7/perks v1.0.1 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
+ github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 // indirect
+ github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
+ github.com/klauspost/compress v1.17.9 // indirect
+ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
+ github.com/prometheus/client_model v0.6.1 // indirect
+ github.com/prometheus/common v0.55.0 // indirect
+ github.com/prometheus/procfs v0.15.1 // indirect
+ golang.org/x/net v0.28.0 // indirect
+ golang.org/x/sys v0.24.0 // indirect
+ golang.org/x/text v0.17.0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
+ google.golang.org/protobuf v1.34.2 // indirect
+)
diff --git a/examples/envoy-als/go.sum b/examples/envoy-als/go.sum
new file mode 100644
index 00000000000..1e30c20ec65
--- /dev/null
+++ b/examples/envoy-als/go.sum
@@ -0,0 +1,40 @@
+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/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg=
+github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
+github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
+github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
+github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
+github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
+github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
+github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
+github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
+github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
+github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
+github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
+github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
+golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
+golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
+google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
+google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
+google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
+google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
diff --git a/examples/envoy-als/main.go b/examples/envoy-als/main.go
new file mode 100644
index 00000000000..9cecabe763a
--- /dev/null
+++ b/examples/envoy-als/main.go
@@ -0,0 +1,115 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package main
+
+import (
+ "log"
+ "net"
+ "net/http"
+
+ alsv2 "github.com/envoyproxy/go-control-plane/envoy/service/accesslog/v2"
+ alsv3 "github.com/envoyproxy/go-control-plane/envoy/service/accesslog/v3"
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promhttp"
+
+ "google.golang.org/grpc"
+)
+
+var (
+ LogCount = prometheus.NewCounterVec(prometheus.CounterOpts{
+ Name: "log_count",
+ Help: "The total number of logs received.",
+ }, []string{"api_version"})
+)
+
+func init() {
+ // Register the summary and the histogram with Prometheus's default registry.
+ prometheus.MustRegister(LogCount)
+}
+
+type ALSServer struct {
+}
+
+func (a *ALSServer) StreamAccessLogs(logStream alsv2.AccessLogService_StreamAccessLogsServer) error {
+ log.Println("Streaming als v2 logs")
+ for {
+ data, err := logStream.Recv()
+ if err != nil {
+ return err
+ }
+
+ httpLogs := data.GetHttpLogs()
+ if httpLogs != nil {
+ LogCount.WithLabelValues("v2").Add(float64(len(httpLogs.LogEntry)))
+ }
+
+ log.Printf("Received v2 log data: %s\n", data.String())
+ }
+}
+
+type ALSServerV3 struct {
+}
+
+func (a *ALSServerV3) StreamAccessLogs(logStream alsv3.AccessLogService_StreamAccessLogsServer) error {
+ log.Println("Streaming als v3 logs")
+ for {
+ data, err := logStream.Recv()
+ if err != nil {
+ return err
+ }
+
+ httpLogs := data.GetHttpLogs()
+ if httpLogs != nil {
+ LogCount.WithLabelValues("v3").Add(float64(len(httpLogs.LogEntry)))
+ }
+
+ log.Printf("Received v3 log data: %s\n", data.String())
+ }
+}
+
+func NewALSServer() *ALSServer {
+ return &ALSServer{}
+}
+
+func NewALSServerV3() *ALSServerV3 {
+ return &ALSServerV3{}
+}
+
+func main() {
+ mux := http.NewServeMux()
+ if err := addMonitor(mux); err != nil {
+ log.Printf("could not establish self-monitoring: %v\n", err)
+ }
+
+ s := &http.Server{
+ Addr: ":19001",
+ Handler: mux,
+ }
+
+ go func() {
+ s.ListenAndServe()
+ }()
+
+ listener, err := net.Listen("tcp", "0.0.0.0:8080")
+ if err != nil {
+ log.Fatalf("Failed to start listener on port 8080: %v", err)
+ }
+
+ var opts []grpc.ServerOption
+ grpcServer := grpc.NewServer(opts...)
+ alsv2.RegisterAccessLogServiceServer(grpcServer, NewALSServer())
+ alsv3.RegisterAccessLogServiceServer(grpcServer, NewALSServerV3())
+ log.Println("Starting ALS Server")
+ if err := grpcServer.Serve(listener); err != nil {
+ log.Fatalf("grpc serve err: %v", err)
+ }
+}
+
+func addMonitor(mux *http.ServeMux) error {
+ mux.Handle("/metrics", promhttp.HandlerFor(prometheus.DefaultGatherer, promhttp.HandlerOpts{EnableOpenMetrics: true}))
+
+ return nil
+}
diff --git a/examples/extension-server/cmd/extension-server/main.go b/examples/extension-server/cmd/extension-server/main.go
index 33e08ddc914..41a9018adc0 100644
--- a/examples/extension-server/cmd/extension-server/main.go
+++ b/examples/extension-server/cmd/extension-server/main.go
@@ -6,18 +6,17 @@
package main
import (
- "fmt"
"log/slog"
"net"
"os"
"os/signal"
"syscall"
- pb "github.com/envoyproxy/gateway/proto/extension"
+ "github.com/exampleorg/envoygateway-extension/internal/extensionserver"
"github.com/urfave/cli/v2"
"google.golang.org/grpc"
- "github.com/exampleorg/envoygateway-extension/internal/extensionserver"
+ pb "github.com/envoyproxy/gateway/proto/extension"
)
func main() {
@@ -56,7 +55,6 @@ func main() {
},
}
app.Run(os.Args)
-
}
var grpcServer *grpc.Server
@@ -65,7 +63,7 @@ func handleSignals(cCtx *cli.Context) error {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGQUIT)
go func() {
- for _ = range c {
+ for range c {
if grpcServer != nil {
grpcServer.Stop()
os.Exit(0)
@@ -83,7 +81,7 @@ func startExtensionServer(cCtx *cli.Context) error {
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
Level: level,
}))
- address := fmt.Sprintf("%s:%d", cCtx.String("host"), cCtx.Int("port"))
+ address := net.JoinHostPort(cCtx.String("host"), cCtx.String("port"))
logger.Info("Starting the extension server", slog.String("host", address))
lis, err := net.Listen("tcp", address)
if err != nil {
diff --git a/examples/extension-server/go.mod b/examples/extension-server/go.mod
index a1c8e2fc44c..865b0df55c4 100644
--- a/examples/extension-server/go.mod
+++ b/examples/extension-server/go.mod
@@ -1,24 +1,25 @@
module github.com/exampleorg/envoygateway-extension
-go 1.22.5
+go 1.23.3
require (
github.com/envoyproxy/gateway v1.0.2
- github.com/envoyproxy/go-control-plane v0.12.1-0.20240612043845-c54ec4ce422d
- github.com/urfave/cli/v2 v2.27.2
- google.golang.org/grpc v1.65.0
- google.golang.org/protobuf v1.34.2
- k8s.io/apimachinery v0.30.3
- sigs.k8s.io/controller-runtime v0.18.4
- sigs.k8s.io/gateway-api v1.1.0
+ github.com/envoyproxy/go-control-plane v0.13.2
+ github.com/envoyproxy/go-control-plane/envoy v1.32.2
+ github.com/urfave/cli/v2 v2.27.5
+ google.golang.org/grpc v1.69.2
+ google.golang.org/protobuf v1.36.1
+ k8s.io/apimachinery v0.32.0
+ sigs.k8s.io/controller-runtime v0.19.3
+ sigs.k8s.io/gateway-api v1.2.1
)
require (
- cel.dev/expr v0.15.0 // indirect
- github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
- github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b // indirect
- github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
- github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
+ cel.dev/expr v0.18.0 // indirect
+ github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
+ github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
@@ -27,19 +28,21 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
+ github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
- golang.org/x/net v0.27.0 // indirect
- golang.org/x/sys v0.22.0 // indirect
- golang.org/x/text v0.16.0 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
+ github.com/x448/float16 v0.8.4 // indirect
+ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
+ golang.org/x/net v0.33.0 // indirect
+ golang.org/x/sys v0.28.0 // indirect
+ golang.org/x/text v0.21.0 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
- gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
- k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect
- sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
- sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
+ k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
+ sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
+ sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect
+ sigs.k8s.io/yaml v1.4.0 // indirect
)
replace github.com/envoyproxy/gateway => ../../
diff --git a/examples/extension-server/go.sum b/examples/extension-server/go.sum
index e6a6ba81bb1..c5f404e8b99 100644
--- a/examples/extension-server/go.sum
+++ b/examples/extension-server/go.sum
@@ -1,34 +1,42 @@
-cel.dev/expr v0.15.0 h1:O1jzfJCQBfL5BFoYktaxwIhuttaQPsVWerH9/EEKx0w=
-cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=
-github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
-github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
-github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw=
-github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
-github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo=
+cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
+github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI=
+github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
+github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
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=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/envoyproxy/go-control-plane v0.12.1-0.20240612043845-c54ec4ce422d h1:RopQsG28t61pLLZRkwzwBsi60yDsOP8RvW47A3eAcGo=
-github.com/envoyproxy/go-control-plane v0.12.1-0.20240612043845-c54ec4ce422d/go.mod h1:5Wkq+JduFtdAXihLmeTJf+tRYIT4KBc2vPXDhwVo1pA=
-github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
-github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
+github.com/envoyproxy/go-control-plane v0.13.2 h1:HoRou/hxH5VAnylep8UAh0jFAllMY0UlP0TwPmIEgYI=
+github.com/envoyproxy/go-control-plane v0.13.2/go.mod h1:mcYj6+AKxG86c/jKeZsCIWv8oLzhR+SJynG0TB94Xw8=
+github.com/envoyproxy/go-control-plane/envoy v1.32.2 h1:zidqwmijfcbyKqVxjQDFx042PgX+p9U+/fu/f9VtSk8=
+github.com/envoyproxy/go-control-plane/envoy v1.32.2/go.mod h1:eR2SOX2IedqlPvmiKjUH7Wu//S602JKI7HPC/L3SRq8=
+github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
+github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
+github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
+github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
-github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
-github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
+github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
-github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
+github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@@ -42,31 +50,45 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
-github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
-github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
-github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
-github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
+github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
+github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
+github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
+github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
-github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
-github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
-github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
-github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
-github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
+github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw=
+go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I=
+go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ=
+go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M=
+go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM=
+go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM=
+go.opentelemetry.io/otel/sdk/metric v1.33.0 h1:Gs5VK9/WUJhNXZgn8MR6ITatvAmKeIuCtNbsP3JkNqU=
+go.opentelemetry.io/otel/sdk/metric v1.33.0/go.mod h1:dL5ykHZmm1B1nVRk9dDjChwDmt81MjVp3gLkQRwKf/Q=
+go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
+go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -76,63 +98,60 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
-golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
+golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
+golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
-golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
+golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
-golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
+golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
+golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
-google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
-google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
-google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
-google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
+google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
+google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
+google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
+google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
+google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ=
-k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04=
-k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc=
-k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
+k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE=
+k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0=
+k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg=
+k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
-k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak=
-k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw=
-sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
-sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM=
-sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
-sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
-sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
+k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
+k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+sigs.k8s.io/controller-runtime v0.19.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw=
+sigs.k8s.io/controller-runtime v0.19.3/go.mod h1:j4j87DqtsThvwTv5/Tc5NFRyyF/RF0ip4+62tbTSIUM=
+sigs.k8s.io/gateway-api v1.2.1 h1:fZZ/+RyRb+Y5tGkwxFKuYuSRQHu9dZtbjenblleOLHM=
+sigs.k8s.io/gateway-api v1.2.1/go.mod h1:EpNfEXNjiYfUJypf0eZ0P5iXA9ekSGWaS1WgPaM42X0=
+sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
+sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
+sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk=
+sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
diff --git a/examples/extension-server/internal/extensionserver/server.go b/examples/extension-server/internal/extensionserver/server.go
index a2776a9f966..2c060869b88 100644
--- a/examples/extension-server/internal/extensionserver/server.go
+++ b/examples/extension-server/internal/extensionserver/server.go
@@ -11,15 +11,15 @@ import (
"fmt"
"log/slog"
- pb "github.com/envoyproxy/gateway/proto/extension"
corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
bav3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/basic_auth/v3"
hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
+ "github.com/exampleorg/envoygateway-extension/api/v1alpha1"
"google.golang.org/protobuf/types/known/anypb"
- "github.com/exampleorg/envoygateway-extension/api/v1alpha1"
+ pb "github.com/envoyproxy/gateway/proto/extension"
)
type Server struct {
diff --git a/examples/extension-server/tools/src/controller-gen/go.mod b/examples/extension-server/tools/src/controller-gen/go.mod
index 3b5da982d27..e1eab3409bc 100644
--- a/examples/extension-server/tools/src/controller-gen/go.mod
+++ b/examples/extension-server/tools/src/controller-gen/go.mod
@@ -1,6 +1,6 @@
module local
-go 1.22.5
+go 1.22.7
require sigs.k8s.io/controller-tools v0.15.0
diff --git a/examples/extension-server/tools/src/controller-gen/pin.go b/examples/extension-server/tools/src/controller-gen/pin.go
index 82c8d1cf3c5..a3fbfac77f7 100644
--- a/examples/extension-server/tools/src/controller-gen/pin.go
+++ b/examples/extension-server/tools/src/controller-gen/pin.go
@@ -4,7 +4,6 @@
// the root of the repo.
//go:build pin
-// +build pin
package ignore
diff --git a/examples/grpc-ext-auth/Dockerfile b/examples/grpc-ext-auth/Dockerfile
new file mode 100644
index 00000000000..f90bb04d8cb
--- /dev/null
+++ b/examples/grpc-ext-auth/Dockerfile
@@ -0,0 +1,23 @@
+FROM golang:1.23.3 AS builder
+
+ARG GO_LDFLAGS=""
+
+WORKDIR /workspace
+COPY go.mod go.sum ./
+RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
+ go mod download
+
+COPY . ./
+RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
+ CGO_ENABLED=0 \
+ GOOS=${TARGETOS} \
+ GOARCH=${TARGETARCH} \
+ go build -o /bin/grpc-ext-auth -ldflags "${GO_LDFLAGS}" .
+
+# Make our production image
+FROM gcr.io/distroless/static-debian11:nonroot
+COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
+COPY --from=builder /bin/grpc-ext-auth /
+
+USER nonroot:nonroot
+ENTRYPOINT ["/grpc-ext-auth"]
diff --git a/examples/grpc-ext-auth/Makefile b/examples/grpc-ext-auth/Makefile
new file mode 100644
index 00000000000..bdcb69d99eb
--- /dev/null
+++ b/examples/grpc-ext-auth/Makefile
@@ -0,0 +1,8 @@
+
+IMAGE_PREFIX ?= envoyproxy/gateway-
+APP_NAME ?= grpc-ext-auth
+TAG ?= latest
+
+.PHONY: docker-buildx
+docker-buildx:
+ docker buildx build . -t $(IMAGE_PREFIX)$(APP_NAME):$(TAG) --build-arg GO_LDFLAGS="$(GO_LDFLAGS)" --load
diff --git a/examples/grpc-ext-auth/go.mod b/examples/grpc-ext-auth/go.mod
new file mode 100644
index 00000000000..fe656cdc112
--- /dev/null
+++ b/examples/grpc-ext-auth/go.mod
@@ -0,0 +1,20 @@
+module github.com/envoyproxy/gateway-grcp-ext-auth
+
+go 1.23.3
+
+require (
+ github.com/envoyproxy/go-control-plane v0.13.1
+ github.com/golang/protobuf v1.5.4
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38
+ google.golang.org/grpc v1.67.1
+)
+
+require (
+ github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 // indirect
+ github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
+ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
+ golang.org/x/net v0.28.0 // indirect
+ golang.org/x/sys v0.24.0 // indirect
+ golang.org/x/text v0.17.0 // indirect
+ google.golang.org/protobuf v1.35.1 // indirect
+)
diff --git a/examples/grpc-ext-auth/go.sum b/examples/grpc-ext-auth/go.sum
new file mode 100644
index 00000000000..03b2f7f5cee
--- /dev/null
+++ b/examples/grpc-ext-auth/go.sum
@@ -0,0 +1,24 @@
+github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg=
+github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
+github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
+github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
+github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
+github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
+golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
+golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
+google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
+google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
+google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
+google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
diff --git a/examples/grpc-ext-auth/main.go b/examples/grpc-ext-auth/main.go
new file mode 100644
index 00000000000..f63b0ec1e85
--- /dev/null
+++ b/examples/grpc-ext-auth/main.go
@@ -0,0 +1,225 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package main
+
+import (
+ "context"
+ "crypto/tls"
+ "crypto/x509"
+ "flag"
+ "fmt"
+ "log"
+ "net"
+ "net/http"
+ "os"
+ "strings"
+
+ envoy_api_v3_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
+ envoy_service_auth_v3 "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3"
+ "github.com/golang/protobuf/ptypes/wrappers"
+ "google.golang.org/genproto/googleapis/rpc/code"
+ "google.golang.org/genproto/googleapis/rpc/status"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/credentials"
+)
+
+var (
+ port int
+ certPath string
+)
+
+func main() {
+ flag.IntVar(&port, "port", 9002, "gRPC port")
+ flag.StringVar(&certPath, "certPath", "", "path to server certificate and private key")
+ flag.Parse()
+
+ lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
+ if err != nil {
+ log.Fatalf("failed to listen to %d: %v", port, err)
+ }
+
+ users := TestUsers()
+
+ // Load TLS credentials
+ creds, err := loadTLSCredentials(certPath)
+ if err != nil {
+ log.Fatalf("Failed to load TLS credentials: %v", err)
+ }
+ gs := grpc.NewServer(grpc.Creds(creds))
+
+ envoy_service_auth_v3.RegisterAuthorizationServer(gs, NewAuthServer(users))
+
+ log.Printf("starting gRPC server on: %d\n", port)
+
+ go func() {
+ err = gs.Serve(lis)
+ if err != nil {
+ log.Fatalf("failed to serve: %v", err)
+ }
+ }()
+
+ http.HandleFunc("/healthz", healthCheckHandler)
+ err = http.ListenAndServe(":8080", nil)
+ if err != nil {
+ log.Fatalf("failed to serve: %v", err)
+ }
+}
+
+type authServer struct {
+ users Users
+}
+
+var _ envoy_service_auth_v3.AuthorizationServer = &authServer{}
+
+// NewAuthServer creates a new authorization server.
+func NewAuthServer(users Users) envoy_service_auth_v3.AuthorizationServer {
+ return &authServer{users}
+}
+
+// Check implements authorization's Check interface which performs authorization check based on the
+// attributes associated with the incoming request.
+func (s *authServer) Check(
+ _ context.Context,
+ req *envoy_service_auth_v3.CheckRequest) (*envoy_service_auth_v3.CheckResponse, error) {
+ authorization := req.Attributes.Request.Http.Headers["authorization"]
+ log.Println(authorization)
+
+ extracted := strings.Fields(authorization)
+ if len(extracted) == 2 && extracted[0] == "Bearer" {
+ valid, user := s.users.Check(extracted[1])
+ if valid {
+ return &envoy_service_auth_v3.CheckResponse{
+ HttpResponse: &envoy_service_auth_v3.CheckResponse_OkResponse{
+ OkResponse: &envoy_service_auth_v3.OkHttpResponse{
+ Headers: []*envoy_api_v3_core.HeaderValueOption{
+ {
+ Append: &wrappers.BoolValue{Value: false},
+ Header: &envoy_api_v3_core.HeaderValue{
+ // For a successful request, the authorization server sets the
+ // x-current-user value.
+ Key: "x-current-user",
+ Value: user,
+ },
+ },
+ },
+ },
+ },
+ Status: &status.Status{
+ Code: int32(code.Code_OK),
+ },
+ }, nil
+ }
+ }
+
+ return &envoy_service_auth_v3.CheckResponse{
+ Status: &status.Status{
+ Code: int32(code.Code_PERMISSION_DENIED),
+ },
+ }, nil
+}
+
+// Users holds a list of users.
+type Users map[string]string
+
+// Check checks if a key could retrieve a user from a list of users.
+func (u Users) Check(key string) (bool, string) {
+ value, ok := u[key]
+ if !ok {
+ return false, ""
+ }
+ return ok, value
+}
+
+func TestUsers() Users {
+ return map[string]string{
+ "token1": "user1",
+ "token2": "user2",
+ "token3": "user3",
+ }
+}
+
+func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
+ certPool, err := loadCA(certPath)
+ if err != nil {
+ log.Fatalf("Could not load CA certificate: %v", err)
+ }
+
+ // Create TLS configuration
+ tlsConfig := &tls.Config{
+ RootCAs: certPool,
+ }
+
+ // Create gRPC dial options
+ opts := []grpc.DialOption{
+ grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)),
+ }
+
+ conn, err := grpc.Dial("localhost:9002", opts...)
+ if err != nil {
+ log.Fatalf("Could not connect: %v", err)
+ }
+ client := envoy_service_auth_v3.NewAuthorizationClient(conn)
+
+ response, err := client.Check(context.Background(), &envoy_service_auth_v3.CheckRequest{
+ Attributes: &envoy_service_auth_v3.AttributeContext{
+ Request: &envoy_service_auth_v3.AttributeContext_Request{
+ Http: &envoy_service_auth_v3.AttributeContext_HttpRequest{
+ Headers: map[string]string{
+ "authorization": "Bearer token1",
+ },
+ },
+ },
+ },
+ })
+ if err != nil {
+ log.Fatalf("Could not check: %v", err)
+ }
+ if response != nil && response.Status.Code == int32(code.Code_OK) {
+ w.WriteHeader(http.StatusOK)
+ } else {
+ w.WriteHeader(http.StatusServiceUnavailable)
+ }
+}
+
+func loadTLSCredentials(certPath string) (credentials.TransportCredentials, error) {
+ // Load server's certificate and private key
+ crt := "server.crt"
+ key := "server.key"
+
+ if certPath != "" {
+ if !strings.HasSuffix(certPath, "/") {
+ certPath = fmt.Sprintf("%s/", certPath)
+ }
+ crt = fmt.Sprintf("%s%s", certPath, crt)
+ key = fmt.Sprintf("%s%s", certPath, key)
+ }
+ certificate, err := tls.LoadX509KeyPair(crt, key)
+ if err != nil {
+ return nil, fmt.Errorf("could not load server key pair: %s", err)
+ }
+
+ // Create a new credentials object
+ creds := credentials.NewTLS(&tls.Config{Certificates: []tls.Certificate{certificate}})
+
+ return creds, nil
+}
+
+func loadCA(caPath string) (*x509.CertPool, error) {
+ ca := x509.NewCertPool()
+ caCertPath := "server.crt"
+ if caPath != "" {
+ if !strings.HasSuffix(caPath, "/") {
+ caPath = fmt.Sprintf("%s/", caPath)
+ }
+ caCertPath = fmt.Sprintf("%s%s", caPath, caCertPath)
+ }
+ caCert, err := os.ReadFile(caCertPath)
+ if err != nil {
+ return nil, fmt.Errorf("could not read ca certificate: %s", err)
+ }
+ ca.AppendCertsFromPEM(caCert)
+ return ca, nil
+}
diff --git a/examples/grpc-ext-proc/Dockerfile b/examples/grpc-ext-proc/Dockerfile
new file mode 100644
index 00000000000..cd0f7db820b
--- /dev/null
+++ b/examples/grpc-ext-proc/Dockerfile
@@ -0,0 +1,22 @@
+FROM golang:1.23.3 AS builder
+
+ARG GO_LDFLAGS=""
+
+WORKDIR /workspace
+COPY go.mod go.sum ./
+RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
+ go mod download
+
+COPY . ./
+RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
+ CGO_ENABLED=0 \
+ GOOS=${TARGETOS} \
+ GOARCH=${TARGETARCH} \
+ go build -o /bin/grpc-ext-proc -ldflags "${GO_LDFLAGS}" .
+
+# Need root user for UDS
+FROM gcr.io/distroless/static-debian11
+COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
+COPY --from=builder /bin/grpc-ext-proc /
+
+ENTRYPOINT ["/grpc-ext-proc"]
diff --git a/examples/grpc-ext-proc/Makefile b/examples/grpc-ext-proc/Makefile
new file mode 100644
index 00000000000..85de130d8fd
--- /dev/null
+++ b/examples/grpc-ext-proc/Makefile
@@ -0,0 +1,8 @@
+
+IMAGE_PREFIX ?= envoyproxy/gateway-
+APP_NAME ?= grpc-ext-proc
+TAG ?= latest
+
+.PHONY: docker-buildx
+docker-buildx:
+ docker buildx build . -t $(IMAGE_PREFIX)$(APP_NAME):$(TAG) --build-arg GO_LDFLAGS="$(GO_LDFLAGS)" --load
diff --git a/examples/grpc-ext-proc/go.mod b/examples/grpc-ext-proc/go.mod
new file mode 100644
index 00000000000..5c7b98ee08e
--- /dev/null
+++ b/examples/grpc-ext-proc/go.mod
@@ -0,0 +1,19 @@
+module github.com/envoyproxy/gateway-grpc-ext-proc
+
+go 1.23.3
+
+require (
+ github.com/envoyproxy/go-control-plane v0.13.1
+ google.golang.org/grpc v1.67.1
+)
+
+require (
+ github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 // indirect
+ github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
+ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
+ golang.org/x/net v0.28.0 // indirect
+ golang.org/x/sys v0.24.0 // indirect
+ golang.org/x/text v0.17.0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
+ google.golang.org/protobuf v1.34.2 // indirect
+)
diff --git a/examples/grpc-ext-proc/go.sum b/examples/grpc-ext-proc/go.sum
new file mode 100644
index 00000000000..d3004724f02
--- /dev/null
+++ b/examples/grpc-ext-proc/go.sum
@@ -0,0 +1,22 @@
+github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg=
+github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
+github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
+github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
+github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
+github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
+golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
+golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
+google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
+google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
+google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
+google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
diff --git a/examples/grpc-ext-proc/main.go b/examples/grpc-ext-proc/main.go
new file mode 100644
index 00000000000..ecdac6bd6be
--- /dev/null
+++ b/examples/grpc-ext-proc/main.go
@@ -0,0 +1,322 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package main
+
+import (
+ "context"
+ "crypto/tls"
+ "crypto/x509"
+ "flag"
+ "fmt"
+ "io"
+ "log"
+ "net"
+ "net/http"
+ "os"
+ "strings"
+
+ "google.golang.org/grpc/credentials"
+
+ envoy_api_v3_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
+ envoy_service_proc_v3 "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
+
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+type extProcServer struct{}
+
+var (
+ port int
+ certPath string
+)
+
+func main() {
+ flag.IntVar(&port, "port", 9002, "gRPC port")
+ flag.StringVar(&certPath, "certPath", "", "path to extProcServer certificate and private key")
+ flag.Parse()
+
+ lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
+ if err != nil {
+ log.Fatalf("failed to listen: %v", err)
+ }
+
+ creds, err := loadTLSCredentials(certPath)
+ if err != nil {
+ log.Fatalf("Failed to load TLS credentials: %v", err)
+ }
+ gs := grpc.NewServer(grpc.Creds(creds))
+ envoy_service_proc_v3.RegisterExternalProcessorServer(gs, &extProcServer{})
+
+ go func() {
+ err = gs.Serve(lis)
+ if err != nil {
+ log.Fatalf("failed to serve: %v", err)
+ }
+ }()
+
+ // Create Unix listener
+ gus := grpc.NewServer(grpc.Creds(creds))
+ envoy_service_proc_v3.RegisterExternalProcessorServer(gus, &extProcServer{})
+
+ udsAddr := "/var/run/ext-proc/extproc.sock"
+ if _, err := os.Stat(udsAddr); err == nil {
+ if err := os.RemoveAll(udsAddr); err != nil {
+ log.Fatalf("failed to remove: %v", err)
+ }
+ }
+
+ ul, err := net.Listen("unix", udsAddr)
+ if err != nil {
+ log.Fatalf("failed to listen: %v", err)
+ }
+
+ err = os.Chmod(udsAddr, 0700)
+ if err != nil {
+ log.Fatalf("failed to set permissions: %v", err)
+ }
+
+ // envoy distroless uid
+ err = os.Chown(udsAddr, 65532, 0)
+ if err != nil {
+ log.Fatalf("failed to set permissions: %v", err)
+ }
+
+ go func() {
+ err = gus.Serve(ul)
+ if err != nil {
+ log.Fatalf("failed to serve: %v", err)
+ }
+ }()
+
+ http.HandleFunc("/healthz", healthCheckHandler)
+ err = http.ListenAndServe(":8080", nil)
+ if err != nil {
+ log.Fatalf("failed to serve: %v", err)
+ }
+}
+
+// used by k8s readiness probes
+// makes a processing request to check if the processor service is healthy
+func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
+ certPool, err := loadCA(certPath)
+ if err != nil {
+ log.Fatalf("Could not load CA certificate: %v", err)
+ }
+
+ // Create TLS configuration
+ tlsConfig := &tls.Config{
+ RootCAs: certPool,
+ ServerName: "grpc-ext-proc.envoygateway",
+ }
+
+ // Create gRPC dial options
+ opts := []grpc.DialOption{
+ grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)),
+ }
+
+ conn, err := grpc.Dial("localhost:9002", opts...)
+ if err != nil {
+ log.Fatalf("Could not connect: %v", err)
+ }
+ client := envoy_service_proc_v3.NewExternalProcessorClient(conn)
+
+ processor, err := client.Process(context.Background())
+ if err != nil {
+ log.Fatalf("Could not check: %v", err)
+ }
+
+ err = processor.Send(&envoy_service_proc_v3.ProcessingRequest{
+ Request: &envoy_service_proc_v3.ProcessingRequest_RequestHeaders{
+ RequestHeaders: &envoy_service_proc_v3.HttpHeaders{},
+ },
+ })
+ if err != nil {
+ log.Fatalf("Could not check: %v", err)
+ }
+
+ response, err := processor.Recv()
+ if err != nil {
+ log.Fatalf("Could not check: %v", err)
+ }
+
+ if response != nil && response.GetRequestHeaders().Response.Status == envoy_service_proc_v3.CommonResponse_CONTINUE {
+ w.WriteHeader(http.StatusOK)
+ } else {
+ w.WriteHeader(http.StatusServiceUnavailable)
+ }
+}
+
+func loadTLSCredentials(certPath string) (credentials.TransportCredentials, error) {
+ // Load extProcServer's certificate and private key
+ crt := "server.crt"
+ key := "server.key"
+
+ if certPath != "" {
+ if !strings.HasSuffix(certPath, "/") {
+ certPath = fmt.Sprintf("%s/", certPath)
+ }
+ crt = fmt.Sprintf("%s%s", certPath, crt)
+ key = fmt.Sprintf("%s%s", certPath, key)
+ }
+ certificate, err := tls.LoadX509KeyPair(crt, key)
+ if err != nil {
+ return nil, fmt.Errorf("could not load extProcServer key pair: %s", err)
+ }
+
+ // Create a new credentials object
+ creds := credentials.NewTLS(&tls.Config{Certificates: []tls.Certificate{certificate}})
+
+ return creds, nil
+}
+
+func loadCA(caPath string) (*x509.CertPool, error) {
+ ca := x509.NewCertPool()
+ caCertPath := "server.crt"
+ if caPath != "" {
+ if !strings.HasSuffix(caPath, "/") {
+ caPath = fmt.Sprintf("%s/", caPath)
+ }
+ caCertPath = fmt.Sprintf("%s%s", caPath, caCertPath)
+ }
+ caCert, err := os.ReadFile(caCertPath)
+ if err != nil {
+ return nil, fmt.Errorf("could not read ca certificate: %s", err)
+ }
+ ca.AppendCertsFromPEM(caCert)
+ return ca, nil
+}
+
+func (s *extProcServer) Process(srv envoy_service_proc_v3.ExternalProcessor_ProcessServer) error {
+ ctx := srv.Context()
+ for {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ default:
+ }
+ req, err := srv.Recv()
+ if err == io.EOF {
+ return nil
+ }
+ if err != nil {
+ return status.Errorf(codes.Unknown, "cannot receive stream request: %v", err)
+ }
+
+ resp := &envoy_service_proc_v3.ProcessingResponse{}
+ switch v := req.Request.(type) {
+ case *envoy_service_proc_v3.ProcessingRequest_RequestHeaders:
+ xdsRouteName := ""
+
+ if req.Attributes != nil {
+ if epa, ok := req.Attributes["envoy.filters.http.ext_proc"]; ok {
+ if rqa, ok := epa.Fields["xds.route_name"]; ok {
+ xdsRouteName = rqa.GetStringValue()
+ }
+ }
+ }
+
+ xrch := ""
+ if v.RequestHeaders != nil {
+ hdrs := v.RequestHeaders.Headers.GetHeaders()
+ for _, hdr := range hdrs {
+ if hdr.Key == "x-request-client-header" {
+ xrch = string(hdr.RawValue)
+ }
+ }
+ }
+
+ rhq := &envoy_service_proc_v3.HeadersResponse{
+ Response: &envoy_service_proc_v3.CommonResponse{
+ HeaderMutation: &envoy_service_proc_v3.HeaderMutation{
+ SetHeaders: []*envoy_api_v3_core.HeaderValueOption{
+ {
+ Header: &envoy_api_v3_core.HeaderValue{
+ Key: "x-request-ext-processed",
+ RawValue: []byte("true"),
+ },
+ },
+ {
+ Header: &envoy_api_v3_core.HeaderValue{
+ Key: "x-request-xds-route-name",
+ RawValue: []byte(xdsRouteName),
+ },
+ },
+ },
+ },
+ },
+ }
+
+ if xrch != "" {
+ rhq.Response.HeaderMutation.SetHeaders = append(rhq.Response.HeaderMutation.SetHeaders,
+ &envoy_api_v3_core.HeaderValueOption{
+ Header: &envoy_api_v3_core.HeaderValue{
+ Key: "x-request-client-header",
+ RawValue: []byte("mutated"),
+ },
+ })
+ rhq.Response.HeaderMutation.SetHeaders = append(rhq.Response.HeaderMutation.SetHeaders,
+ &envoy_api_v3_core.HeaderValueOption{
+ Header: &envoy_api_v3_core.HeaderValue{
+ Key: "x-request-client-header-received",
+ RawValue: []byte(xrch),
+ },
+ })
+ }
+
+ resp = &envoy_service_proc_v3.ProcessingResponse{
+ Response: &envoy_service_proc_v3.ProcessingResponse_RequestHeaders{
+ RequestHeaders: rhq,
+ },
+ }
+
+ break
+ case *envoy_service_proc_v3.ProcessingRequest_ResponseHeaders:
+
+ respXDSRouteName := ""
+
+ if req.Attributes != nil {
+ if epa, ok := req.Attributes["envoy.filters.http.ext_proc"]; ok {
+ if rsa, ok := epa.Fields["xds.route_name"]; ok {
+ respXDSRouteName = rsa.GetStringValue()
+ }
+ }
+ }
+ rhq := &envoy_service_proc_v3.HeadersResponse{
+ Response: &envoy_service_proc_v3.CommonResponse{
+ HeaderMutation: &envoy_service_proc_v3.HeaderMutation{
+ SetHeaders: []*envoy_api_v3_core.HeaderValueOption{
+ {
+ Header: &envoy_api_v3_core.HeaderValue{
+ Key: "x-response-ext-processed",
+ RawValue: []byte("true"),
+ },
+ },
+ {
+ Header: &envoy_api_v3_core.HeaderValue{
+ Key: "x-response-xds-route-name",
+ RawValue: []byte(respXDSRouteName),
+ },
+ },
+ },
+ },
+ },
+ }
+ resp = &envoy_service_proc_v3.ProcessingResponse{
+ Response: &envoy_service_proc_v3.ProcessingResponse_ResponseHeaders{
+ ResponseHeaders: rhq,
+ },
+ }
+ break
+ default:
+ log.Printf("Unknown Request type %v\n", v)
+ }
+ if err := srv.Send(resp); err != nil {
+ log.Printf("send error %v", err)
+ }
+ }
+}
diff --git a/examples/http-ext-auth/Dockerfile b/examples/http-ext-auth/Dockerfile
new file mode 100644
index 00000000000..f3e3ef5d614
--- /dev/null
+++ b/examples/http-ext-auth/Dockerfile
@@ -0,0 +1,6 @@
+FROM node:19-bullseye
+
+COPY ./http-ext-auth.js .
+
+ENTRYPOINT ["node", "./http-ext-auth.js"]
+
diff --git a/examples/http-ext-auth/Makefile b/examples/http-ext-auth/Makefile
new file mode 100644
index 00000000000..a0fe0063528
--- /dev/null
+++ b/examples/http-ext-auth/Makefile
@@ -0,0 +1,8 @@
+
+IMAGE_PREFIX ?= envoyproxy/gateway-
+APP_NAME ?= http-ext-auth
+TAG ?= latest
+
+.PHONY: docker-buildx
+docker-buildx:
+ docker buildx build . -t $(IMAGE_PREFIX)$(APP_NAME):$(TAG) --build-arg GO_LDFLAGS="$(GO_LDFLAGS)" --load
diff --git a/examples/http-ext-auth/http-ext-auth.js b/examples/http-ext-auth/http-ext-auth.js
new file mode 100644
index 00000000000..17ece921822
--- /dev/null
+++ b/examples/http-ext-auth/http-ext-auth.js
@@ -0,0 +1,38 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+const Http = require("http");
+const path = require("path");
+
+const tokens = {
+ "token1": "user1",
+ "token2": "user2",
+ "token3": "user3"
+};
+
+const server = new Http.Server((req, res) => {
+ const authorization = req.headers["authorization"] || "";
+ const extracted = authorization.split(" ");
+ if (extracted.length === 2 && extracted[0] === "Bearer") {
+ const user = checkToken(extracted[1]);
+ console.log(`token: "${extracted[1]}" user: "${user}`);
+ if (user !== undefined) {
+ // The authorization server returns a response with "x-current-user" header for a successful
+ // request.
+ res.writeHead(200, { "x-current-user": user });
+ return res.end();
+ }
+ }
+ res.writeHead(403);
+ res.end();
+});
+
+const port = process.env.PORT || 9002;
+server.listen(port);
+console.log(`starting HTTP server on: ${port}`);
+
+function checkToken(token) {
+ return tokens[token];
+}
\ No newline at end of file
diff --git a/examples/kubernetes/ext-proc-grpc-service.yaml b/examples/kubernetes/ext-proc-grpc-service.yaml
index 23b90b104cb..b52625d6a01 100644
--- a/examples/kubernetes/ext-proc-grpc-service.yaml
+++ b/examples/kubernetes/ext-proc-grpc-service.yaml
@@ -361,7 +361,7 @@ spec:
- sh
- "-c"
- "cp -a /app /app-live && cd /app-live && go run . --certPath=/app-live/certs/ "
- image: golang:1.22.5-alpine
+ image: golang:1.23.1-alpine
ports:
- containerPort: 8000
volumeMounts:
diff --git a/examples/kubernetes/jwt/README.md b/examples/kubernetes/jwt/README.md
new file mode 100644
index 00000000000..cc4d6eacaff
--- /dev/null
+++ b/examples/kubernetes/jwt/README.md
@@ -0,0 +1,3 @@
+The JWKS and private key in this directory are for testing purposes only and should not be considered confidential. Please do not use them in a production environment.
+
+A new JWT token can be generated using tools like https://www.scottbrady91.com/tools/jwt .
\ No newline at end of file
diff --git a/examples/kubernetes/jwt/jwks.json b/examples/kubernetes/jwt/jwks.json
index 6cd882726be..b58d8e04fb3 100644
--- a/examples/kubernetes/jwt/jwks.json
+++ b/examples/kubernetes/jwt/jwks.json
@@ -1 +1,22 @@
-{"keys":[{"kty":"RSA","n":"u1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0_IzW7yWR7QkrmBL7jTKEn5u-qKhbwKfBstIs-bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW_VDL5AaWTg0nLVkjRo9z-40RQzuVaE8AkAFmxZzow3x-VJYKdjykkJ0iT9wCS0DRTXu269V264Vf_3jvredZiKRkgwlL9xNAwxXFg0x_XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC-9aGVd-Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmw","e":"AQAB","alg":"RS256","use":"sig"}]}
+{
+ "keys": [
+ {
+ "kty": "RSA",
+ "n": "u1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0_IzW7yWR7QkrmBL7jTKEn5u-qKhbwKfBstIs-bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW_VDL5AaWTg0nLVkjRo9z-40RQzuVaE8AkAFmxZzow3x-VJYKdjykkJ0iT9wCS0DRTXu269V264Vf_3jvredZiKRkgwlL9xNAwxXFg0x_XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC-9aGVd-Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmw",
+ "e": "AQAB",
+ "alg": "RS256",
+ "use": "sig"
+ },
+ {
+ "alg": "RS256",
+ "e": "AQAB",
+ "key_ops": [
+ "verify"
+ ],
+ "kty": "RSA",
+ "n": "xOHb-i1WDfeAvsbXTSOtosl3hCUDHQ8fRDqX_Rt998-hZDJmAoPOu4J-wcwq5aZtSn_iWUYLcK2WmC_1n-p1eyc-Pl4CBnxF7LUjCk-WGhniaCzXC5I5RON6c5N-MdE0UfukK0PM0zD3iQonZq0fIsnOYyFdYdWvQ5XW-C2aLlq2FUKrjmhAav10jIC0KGd2dHRzauzfLMUmt_iMnpU84Xrur1zRYzBO4D90rN0ypC2HH7o_zI8Osx4o1L8BScW78545sWyVbaprhBV1I2Sa4SH3NAc25ej3RIh-f13Yu97FVfO0AIG4VfFiaMmsTqNTCiBkM20tXD2Z-cHJTKemXzFgInJoqFLAkHLzJ0lPvAkKOgAOufLHa7RA-C276OXd72IXPsL1UOLN4sjhGqTtaynVa00yuHdi3f4-aoy9F9SUJeWfPg--nZNLzuI0eyufsTFywnx1bTQ_kdYlEr0dRE5sujlMk3cZ7FmOQRvcjA9MxFzoVKMmlZc6LMCgqw-P",
+ "use": "sig",
+ "kid": "b520b3c2c4bd75a10e9cebc9576933dc"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/examples/kubernetes/jwt/key.json b/examples/kubernetes/jwt/key.json
new file mode 100644
index 00000000000..6fbf5bb2231
--- /dev/null
+++ b/examples/kubernetes/jwt/key.json
@@ -0,0 +1,17 @@
+{
+ "alg": "RS256",
+ "d": "URyb_B3hbi-hovdYjDc-ueo2iwKUncw1HW7mXyiMZSPtYdJBpJeY_Ddu8Xij06kVLbQyFIV_ARUDDf_0OcXmUK6CPj-Mpg9c34Bgx0aymF5BoJmYnvPHFFKDiEojm3KNE5mQsSJlqDxsPtEoGm0IftSVatG8Hyph4n5A6k4fTymgCnJFK45Xu7xf3-LGVj8J1kCDrHGaIF-46-JCTLM_OcXjv-uFeE_Wrxx1fSJEUs9O9AtPbX8ilzi9qahnZ3VGmG1sSv0IPy1zUcRqF0nHVi4FP4yK-jZNbGvYobqlf-CpW6FKRNwKzc9a8QfnJB-bA4DQkHZBqKOLpMlPgGQj4Sgp4OnaBrJhXO4gLkXlhLpQNjr74qZr0KYR34MsVJIbCT0m6P1HrH1Yz-k8PIWE1LfY4Ku5ECpJOP9PCqd4vcUM4ErON08MozvSvALkuzgvWC7jjkHECSaRvRKhA6cEuBPLlzwUSWPRiso6BC9TvaEmbg2zk-xBtMfiKdtc9NPB",
+ "dp": "vAzERP3CMHHpBMK_0--UPaoTcfTDlcR6-2oRfjkbb3sfbryZJkoCrnlBBbFAnbSkCIrJL9Ig2lfEpK44OQJJ48AYja5z2APQyTgoOQMpp61OH8AWgvnupLNtWdhwYQgDkb276pAcPBkgRxXt29qW_Tvbcq-vcmV9NrqEWrJj_Os7gQvVDTgagaQZ3eH7eHqKCoAcAEwKL1SOH7DEh-LSX9N2G54tU11RFSmuiGMZ_XzU-hFmQN210sRckjHivCvR",
+ "dq": "yT4AWazCtcgW44VdhSlpebeMnz591P9KA41_l8vDALCBIjbom0wX5BZaaLaPsUPvfGkIOduCs7cJWzBPwOrd_BLenqd7rsHlhAz5aBVj0aXenUGwYQ8DaZzrB_wmPrJHkyzT9HOJ1jmiC5op-igcNSHrPfwFJ5K-bjUHJE4zIMmsMzi8XoWIj52uyRdXAq1u1t12Hc3_g_Fy5PugufrNIh8bMBw8wsEfTnMc21Y5s7xTTFouf4RUgVP5oBCe12Lh",
+ "e": "AQAB",
+ "key_ops": [
+ "sign"
+ ],
+ "kty": "RSA",
+ "n": "xOHb-i1WDfeAvsbXTSOtosl3hCUDHQ8fRDqX_Rt998-hZDJmAoPOu4J-wcwq5aZtSn_iWUYLcK2WmC_1n-p1eyc-Pl4CBnxF7LUjCk-WGhniaCzXC5I5RON6c5N-MdE0UfukK0PM0zD3iQonZq0fIsnOYyFdYdWvQ5XW-C2aLlq2FUKrjmhAav10jIC0KGd2dHRzauzfLMUmt_iMnpU84Xrur1zRYzBO4D90rN0ypC2HH7o_zI8Osx4o1L8BScW78545sWyVbaprhBV1I2Sa4SH3NAc25ej3RIh-f13Yu97FVfO0AIG4VfFiaMmsTqNTCiBkM20tXD2Z-cHJTKemXzFgInJoqFLAkHLzJ0lPvAkKOgAOufLHa7RA-C276OXd72IXPsL1UOLN4sjhGqTtaynVa00yuHdi3f4-aoy9F9SUJeWfPg--nZNLzuI0eyufsTFywnx1bTQ_kdYlEr0dRE5sujlMk3cZ7FmOQRvcjA9MxFzoVKMmlZc6LMCgqw-P",
+ "p": "7m9XI2SOtfdUd-BTKSoot9bgo5oKHcG3pilZtNlqgf5o47rHeSQj8Js85PL-2IXGDuRkTA08uTzQtoPEwsGb8aB96KhSw3SSqtEN_hNFCUQ4AuxWtXj5nTEudqhyFHyYb5U-6_iVrKk_rJYI4l1dRSe0ePuIgmHJOSJUBnPFHiYURKmI3F2MCLXD3PQKbtBYx24QP0bvsTl6uz_uh5_EvPLBgtCJf0ey6D2DHt-4NQxp-_13PCBxt_ARi6lAYG8D",
+ "q": "02Lf5WZuXf0ZBvnug8lwkZ1a2pe0MG_-b6KHMaUN3su3uyqvB8x6b9wEl3UN-4z8OgDfWewYFxU5v3DMPY6ecMoMFfOzSApTEimLsJ_4i3qqxFvVeG5w0jX7nyGBvCdIuqjQYGd03P2BpXQwiFzJ7Sai4Dj_IOPUBM59TCR3R-fk8I9PoTXDXG1di6DwpXRvfYoUypxufvhQcmvBELB-sNgbX2LjVwJ4ZjniMFSkjvGNm88BH32SMRMuh3oSFiGF",
+ "qi": "wh-Gs9spzz9ogGpj_XSkHguvHayVqLzDK9GVbdXUO-bOYvZkvQO37GDBBRv39drYQrpgivT-iwgtWn6ESQ1atxcx1I6IXtAi9CZUJeBH7ipuOi5GPr_igphr0Z9O2a7Bwv3ZwwnuoseGYIW4ybPj93D1P2nHKcoh4u5dpSpXuy3qh4urAtVkivEXtxPPQdTkoizwGPAa19-Tyzv8Xrt3W6M2rCBQa8mpLkBHYhkgxfDx8olrerXxT11kMLlqFcwN",
+ "use": "sig",
+ "kid": "b520b3c2c4bd75a10e9cebc9576933dc"
+ }
\ No newline at end of file
diff --git a/examples/preserve-case-backend/Dockerfile b/examples/preserve-case-backend/Dockerfile
new file mode 100644
index 00000000000..46d71ff22b5
--- /dev/null
+++ b/examples/preserve-case-backend/Dockerfile
@@ -0,0 +1,22 @@
+FROM golang:1.23.3 AS builder
+
+ARG GO_LDFLAGS=""
+
+WORKDIR /workspace
+COPY go.mod go.sum ./
+RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
+ go mod download
+
+COPY . ./
+RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
+ CGO_ENABLED=0 \
+ GOOS=${TARGETOS} \
+ GOARCH=${TARGETARCH} \
+ go build -o /bin/preserve-case-backend -ldflags "${GO_LDFLAGS}" .
+
+# Need root user for UDS
+FROM gcr.io/distroless/static-debian11
+COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
+COPY --from=builder /bin/preserve-case-backend /
+
+ENTRYPOINT ["/preserve-case-backend"]
diff --git a/examples/preserve-case-backend/Makefile b/examples/preserve-case-backend/Makefile
new file mode 100644
index 00000000000..159725237f4
--- /dev/null
+++ b/examples/preserve-case-backend/Makefile
@@ -0,0 +1,8 @@
+
+IMAGE_PREFIX ?= envoyproxy/gateway-
+APP_NAME ?= preserve-case-backend
+TAG ?= latest
+
+.PHONY: docker-buildx
+docker-buildx:
+ docker buildx build . -t $(IMAGE_PREFIX)$(APP_NAME):$(TAG) --build-arg GO_LDFLAGS="$(GO_LDFLAGS)" --load
diff --git a/examples/preserve-case-backend/go.mod b/examples/preserve-case-backend/go.mod
new file mode 100644
index 00000000000..22c616a7ba3
--- /dev/null
+++ b/examples/preserve-case-backend/go.mod
@@ -0,0 +1,11 @@
+module github.com/envoyproxy/gateway-preserve-case-backend
+
+go 1.23.3
+
+require github.com/valyala/fasthttp v1.51.0
+
+require (
+ github.com/andybalholm/brotli v1.0.5 // indirect
+ github.com/klauspost/compress v1.17.0 // indirect
+ github.com/valyala/bytebufferpool v1.0.0 // indirect
+)
diff --git a/examples/preserve-case-backend/go.sum b/examples/preserve-case-backend/go.sum
new file mode 100644
index 00000000000..cfe8f6c10e5
--- /dev/null
+++ b/examples/preserve-case-backend/go.sum
@@ -0,0 +1,8 @@
+github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
+github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
+github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
+github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
diff --git a/examples/preserve-case-backend/main.go b/examples/preserve-case-backend/main.go
new file mode 100644
index 00000000000..1922d3c9b95
--- /dev/null
+++ b/examples/preserve-case-backend/main.go
@@ -0,0 +1,42 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "net"
+
+ "github.com/valyala/fasthttp"
+)
+
+func HandleFastHTTP(ctx *fasthttp.RequestCtx) {
+ ctx.QueryArgs().VisitAll(func(key, value []byte) {
+ if string(key) == "headers" {
+ ctx.Response.Header.Add(string(value), "PrEsEnT")
+ }
+ })
+ headers := map[string][]string{}
+ ctx.Request.Header.VisitAll(func(key, value []byte) {
+ headers[string(key)] = append(headers[string(key)], string(value))
+ })
+ if d, err := json.MarshalIndent(headers, "", " "); err != nil {
+ ctx.Error(fmt.Sprintf("%s", err), fasthttp.StatusBadRequest)
+ } else {
+ fmt.Fprintf(ctx, string(d)+"\n")
+ }
+}
+
+func main() {
+ s := fasthttp.Server{
+ Handler: HandleFastHTTP,
+ DisableHeaderNamesNormalizing: true,
+ }
+ log.Printf("Starting on port 8000")
+ l, _ := net.Listen("tcp", ":8000")
+ log.Fatal(s.Serve(l))
+}
diff --git a/examples/standalone/quickstart.yaml b/examples/standalone/quickstart.yaml
new file mode 100644
index 00000000000..4ccf2ce8efd
--- /dev/null
+++ b/examples/standalone/quickstart.yaml
@@ -0,0 +1,46 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+ name: eg
+spec:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+ name: eg
+spec:
+ gatewayClassName: eg
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 8888
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: backend
+spec:
+ parentRefs:
+ - name: eg
+ hostnames:
+ - "www.example.com"
+ rules:
+ - backendRefs:
+ - group: "gateway.envoyproxy.io"
+ kind: Backend
+ name: backend
+ matches:
+ - path:
+ type: PathPrefix
+ value: /
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend
+spec:
+ endpoints:
+ - ip:
+ address: 0.0.0.0 # this address is for demo purpose only, do not use it in production!
+ port: 3000
diff --git a/examples/static-file-server/Dockerfile b/examples/static-file-server/Dockerfile
new file mode 100644
index 00000000000..1f1268a2197
--- /dev/null
+++ b/examples/static-file-server/Dockerfile
@@ -0,0 +1,23 @@
+FROM golang:1.23.3 AS builder
+
+ARG GO_LDFLAGS=""
+
+WORKDIR /workspace
+COPY go.mod go.sum ./
+RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
+ go mod download
+
+COPY . ./
+RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
+ CGO_ENABLED=0 \
+ GOOS=${TARGETOS} \
+ GOARCH=${TARGETARCH} \
+ go build -o /bin/static-file-server -ldflags "${GO_LDFLAGS}" .
+
+# Need root user for UDS
+FROM gcr.io/distroless/static-debian11
+COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
+COPY --from=builder /bin/static-file-server /
+COPY files/ files/
+
+ENTRYPOINT ["/static-file-server"]
diff --git a/examples/static-file-server/Makefile b/examples/static-file-server/Makefile
new file mode 100644
index 00000000000..a4e59d1e3dd
--- /dev/null
+++ b/examples/static-file-server/Makefile
@@ -0,0 +1,8 @@
+
+IMAGE_PREFIX ?= envoyproxy/gateway-
+APP_NAME ?= static-file-server
+TAG ?= latest
+
+.PHONY: docker-buildx
+docker-buildx:
+ docker buildx build . -t $(IMAGE_PREFIX)$(APP_NAME):$(TAG) --build-arg GO_LDFLAGS="$(GO_LDFLAGS)" --load
diff --git a/examples/static-file-server/README.md b/examples/static-file-server/README.md
new file mode 100644
index 00000000000..7cb2417e3cd
--- /dev/null
+++ b/examples/static-file-server/README.md
@@ -0,0 +1,10 @@
+# Static File Server
+
+This example demonstrates how to create a simple static file server using the `http` package.
+Which serves files used by e2e tests.
+
+- test/e2e/testdata/authorization-jwt.yaml
+- test/e2e/testdata/jwt.yaml
+- test/e2e/testdata/jwt-optional.yaml
+- test/e2e/testdata/ratelimit-based-jwt-claims.yaml
+- test/e2e/testdata/wasm-http.yaml
\ No newline at end of file
diff --git a/examples/static-file-server/files/jwt/jwks.json b/examples/static-file-server/files/jwt/jwks.json
new file mode 100644
index 00000000000..b58d8e04fb3
--- /dev/null
+++ b/examples/static-file-server/files/jwt/jwks.json
@@ -0,0 +1,22 @@
+{
+ "keys": [
+ {
+ "kty": "RSA",
+ "n": "u1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0_IzW7yWR7QkrmBL7jTKEn5u-qKhbwKfBstIs-bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW_VDL5AaWTg0nLVkjRo9z-40RQzuVaE8AkAFmxZzow3x-VJYKdjykkJ0iT9wCS0DRTXu269V264Vf_3jvredZiKRkgwlL9xNAwxXFg0x_XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC-9aGVd-Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmw",
+ "e": "AQAB",
+ "alg": "RS256",
+ "use": "sig"
+ },
+ {
+ "alg": "RS256",
+ "e": "AQAB",
+ "key_ops": [
+ "verify"
+ ],
+ "kty": "RSA",
+ "n": "xOHb-i1WDfeAvsbXTSOtosl3hCUDHQ8fRDqX_Rt998-hZDJmAoPOu4J-wcwq5aZtSn_iWUYLcK2WmC_1n-p1eyc-Pl4CBnxF7LUjCk-WGhniaCzXC5I5RON6c5N-MdE0UfukK0PM0zD3iQonZq0fIsnOYyFdYdWvQ5XW-C2aLlq2FUKrjmhAav10jIC0KGd2dHRzauzfLMUmt_iMnpU84Xrur1zRYzBO4D90rN0ypC2HH7o_zI8Osx4o1L8BScW78545sWyVbaprhBV1I2Sa4SH3NAc25ej3RIh-f13Yu97FVfO0AIG4VfFiaMmsTqNTCiBkM20tXD2Z-cHJTKemXzFgInJoqFLAkHLzJ0lPvAkKOgAOufLHa7RA-C276OXd72IXPsL1UOLN4sjhGqTtaynVa00yuHdi3f4-aoy9F9SUJeWfPg--nZNLzuI0eyufsTFywnx1bTQ_kdYlEr0dRE5sujlMk3cZ7FmOQRvcjA9MxFzoVKMmlZc6LMCgqw-P",
+ "use": "sig",
+ "kid": "b520b3c2c4bd75a10e9cebc9576933dc"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/examples/static-file-server/files/wasm/envoy_filter_http_wasm_example.wasm b/examples/static-file-server/files/wasm/envoy_filter_http_wasm_example.wasm
new file mode 100644
index 00000000000..df2554e971e
Binary files /dev/null and b/examples/static-file-server/files/wasm/envoy_filter_http_wasm_example.wasm differ
diff --git a/examples/static-file-server/go.mod b/examples/static-file-server/go.mod
new file mode 100644
index 00000000000..69cc2a932da
--- /dev/null
+++ b/examples/static-file-server/go.mod
@@ -0,0 +1,3 @@
+module github.com/envoyproxy/static-file-server
+
+go 1.23.3
diff --git a/examples/static-file-server/go.sum b/examples/static-file-server/go.sum
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/examples/static-file-server/main.go b/examples/static-file-server/main.go
new file mode 100644
index 00000000000..1a82c1ae37f
--- /dev/null
+++ b/examples/static-file-server/main.go
@@ -0,0 +1,39 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package main
+
+import (
+ "flag"
+ "log"
+ "net/http"
+ "os"
+ "path"
+)
+
+var (
+ port string
+ directory string
+ certPath string
+)
+
+func main() {
+ flag.StringVar(&port, "port", "8080", "port to serve on")
+ flag.StringVar(&directory, "dir", "./files", "the directory of static file to host")
+ flag.StringVar(&certPath, "certPath", "/etc/certs", "path to extProcServer certificate and private key")
+ flag.Parse()
+
+ http.Handle("/", http.FileServer(http.Dir(directory)))
+
+ if _, err := os.Stat(path.Join(certPath, "tls.crt")); err != nil {
+ log.Printf("Serving %s on HTTP port: %s\n", directory, port)
+ log.Fatal(http.ListenAndServe(":"+port, nil))
+ return
+ }
+
+ log.Printf("Serving %s on HTTPS port: %s\n", directory, port)
+ log.Fatal(http.ListenAndServeTLS(":"+port,
+ path.Join(certPath, "tls.crt"), path.Join(certPath, "tls.key"), nil))
+}
diff --git a/examples/static-file-server/manifests/http.yaml b/examples/static-file-server/manifests/http.yaml
new file mode 100644
index 00000000000..e21fec0179c
--- /dev/null
+++ b/examples/static-file-server/manifests/http.yaml
@@ -0,0 +1,33 @@
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: static-file-server
+spec:
+ selector:
+ app: static-file-server
+ ports:
+ - protocol: TCP
+ port: 443
+ targetPort: 8443
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: static-file-server
+ labels:
+ app: static-file-server
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: static-file-server
+ template:
+ metadata:
+ labels:
+ app: static-file-server
+ spec:
+ containers:
+ - name: static-file-server
+ image: envoyproxy/gateway-static-file-server
+ imagePullPolicy: IfNotPresent
diff --git a/examples/static-file-server/manifests/httproute.yaml b/examples/static-file-server/manifests/httproute.yaml
new file mode 100644
index 00000000000..beaefdbb423
--- /dev/null
+++ b/examples/static-file-server/manifests/httproute.yaml
@@ -0,0 +1,22 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: backend
+spec:
+ parentRefs:
+ - name: eg
+ rules:
+ - backendRefs:
+ - group: ""
+ kind: Service
+ name: static-file-server
+ port: 443
+ weight: 1
+ matches:
+ - path:
+ type: PathPrefix
+ value: /jwt
+ - path:
+ type: PathPrefix
+ value: /wasm
+---
diff --git a/examples/static-file-server/manifests/tls.yaml b/examples/static-file-server/manifests/tls.yaml
new file mode 100644
index 00000000000..d277452efd1
--- /dev/null
+++ b/examples/static-file-server/manifests/tls.yaml
@@ -0,0 +1,95 @@
+apiVersion: v1
+data:
+ tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURZVENDQWttZ0F3SUJBZ0lSQUpiK2x5QTJqZCtlUmRMTzR4Sm5kWVF3RFFZSktvWklodmNOQVFFTEJRQXcKUWpFVE1CRUdBMVVFQ2hNS1JXNTJiM2xRY205NGVURVFNQTRHQTFVRUN4TUhSMkYwWlhkaGVURVpNQmNHQTFVRQpBeE1RUlc1MmIza2dSMkYwWlhkaGVTQkRRVEFnRncweU5EQXpNVEF4TlRNeU1UZGFHQTh5TVRJME1ETXhNREUyCk16SXhOMW93SkRFUU1BNEdBMVVFQ2hNSFFXTnRaU0JEYnpFUU1BNEdBMVVFQXhNSFpHVm1ZWFZzZERDQ0FTSXcKRFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtGUnI2cVV1WFN1N3J5bHcvVmZXbm1kM0RXWgpTcGxDUFR6QUh1V3NpOVVrbW5rTVhNOXN3Y1VQZFUyd2NNSHd1bDNpNGJwTlRkUGVWRG04K3JUVXNmaHMySWZuCmhHNW9WV0JnTkJXVEYzRnpiUmgvc3orK3p6MlBnZ0Fpb3NjYmEyVm5qaExyOUM3a0Q3QnRYNVlvSENGQ3lhT24Kem9WNVdNSnBBNHNCeGdOdkpXSU5aRUNnOUlmSWxSMDZMTGlNTXJCRTVRS2cvTG5EUkpuTEZEVFZCTDdzallpVQpZdVZtRWczMXJaOVpsNXViZ09xSU9uU2ROM2RNM1hhUnBCTWFGVXg5UDlQcmhjS3l5NVRkQ3g2MHBIYXMvaFIxCmFjcEp5VmdmRFVDdXNUUFphVFo1eXM0cmhib1l3WDN5cnZKN29lMHM4QmRZU2thT1NBTElDaU9PWGtVQ0F3RUEKQWFOdU1Hd3dEZ1lEVlIwUEFRSC9CQVFEQWdXZ01CTUdBMVVkSlFRTU1Bb0dDQ3NHQVFVRkJ3TUJNQXdHQTFVZApFd0VCL3dRQ01BQXdId1lEVlIwakJCZ3dGb0FVVXBQMWFaMU0yS0l1UFBXck5QRFYyYzVDbmdvd0ZnWURWUjBSCkJBOHdEWUlMWlhoaGJYQnNaUzVqYjIwd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBMkk1MmhrcEwwTXZmejQKeDk3ZjV6dlR5a1VtRWhDSVowN0g0anM0WVg2a1hLWVBzRDBlaGJFbzZUSWgyMkpWMkpyWnRuaWhMQnRGQStuUQp2Zk9QcE1LRnJMUU1DWVozMk9Na045T1pWbmNyMmpQNzNhaE9SaWloaGVBczJYTUtybHZmVWVKTFJrSlBlSVB6CnR2TlVacWExMmZ4T0Jsdy9hV1NqVk9lRDVMVm5nUStrQksydGRoL08xSjFWRGgzdVU3RHNZUThmRm1UcWR6ZzYKUWhtbjhaTXFIS3lNeitOdkt1d1h5eEtyeFZKVEl1QzJXZHhGWlZZMzdtZzJ5Vm9OdFhpSFNQMXpxVWV4SHNEKwpzUDBsZy9jUDdlaitOY3Q5WnpudUZBc2U4cUNDZnlaL2hPQ2NCblZabG1GUFgzRCtJSEpVWUpGaWVkYndsZHljCmw1eG1jaFU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBb1ZHdnFwUzVkSzd1dktYRDlWOWFlWjNjTlpsS21VSTlQTUFlNWF5TDFTU2FlUXhjCnoyekJ4UTkxVGJCd3dmQzZYZUxodWsxTjA5NVVPYno2dE5TeCtHelloK2VFYm1oVllHQTBGWk1YY1hOdEdIK3oKUDc3UFBZK0NBQ0tpeHh0clpXZU9FdXYwTHVRUHNHMWZsaWdjSVVMSm82Zk9oWGxZd21rRGl3SEdBMjhsWWcxawpRS0QwaDhpVkhUb3N1SXd5c0VUbEFxRDh1Y05FbWNzVU5OVUV2dXlOaUpSaTVXWVNEZld0bjFtWG01dUE2b2c2CmRKMDNkMHpkZHBHa0V4b1ZUSDAvMCt1RndyTExsTjBMSHJTa2RxeitGSFZweWtuSldCOE5RSzZ4TTlscE5ubksKeml1RnVoakJmZkt1OG51aDdTendGMWhLUm81SUFzZ0tJNDVlUlFJREFRQUJBb0lCQVFDVGlZUGh2TGVJa2R6aQpSN0RhbnVTK1NiUDJpVVlDdU9RTXhhRDhhVHhTS1hIbHQzckNjak1kcVMrZFovc1lSTFFOM2N5WWVNN3ZNRzFUCmlSUzVnYlZyQVJGZjZrdmlOaVd2U1EwWmxqZGdtVEp6cjRjZWk4STZDUi9hUTlNZnltSUVraHNNRHlSNkpqWjcKSXV6REJkZ0VTM0xpN0R3ak1vSU0rOEl6eGVGMWpTT1ErTjlLcTB3QzMzVzFuOVdIYXZWcWZvcjI0bmVySG9FcwozNmlUMncvdkU1dFJBTFlEbjh6MFp5YUM1d3Nnb3FyTG5UWXlMcnVKWnNGa1NxN25GWEE3cjhXL0dLQjBoL3ZaCmNzYkRlWU1WMjJNckdRTzhYSlAwM3J0cm9DQWJmUUhRd3lEbnpsTFJ3blNGRmhjV0F5UW9qbkozb0RQbzhZaXoKam1meVd5WlpBb0dCQU0vZGtqMGhFZm05SHBBL1dyTGVEb0V5WWtKL3N1R3RyWlpSNS9INnJieHphQ2FlQ3B0UApZQ25JcnBoMjRVYWFvaXFJY0pnazRXRjBmU3RhRnh0SkxSYXpBVElUUFlCZjF0OEEwYkhjN3UxMExiWlZkMG5uCk1lWVJPYlhzQXlvdmxNcm1ZclBPWWFXSEtJL1oyT3NLeC83UkhTcnEwZm1ZcUFYSXpzK2V1Ryt6QW9HQkFNYXMKem9YdlJwVDZGNndYaU5QemFqamc5MHJFMFhZZ0g3VkEvWHJsbUp5MVFRYy8rZzJ1ZXVYMGJ5aVhYY0FMY3BINAoybFlYcEZaelNPRkd6Z01DMEtuQkJyWmxsYWIweUczbWhsWjRtbkFhbmtSUFh4bWpDdmgvZmtkYStlQ1RCMFdHCjBOY3RQSFVvSk9GNWpLNmtxVy9rWVpkWVRPV1FjczNybURFWCtENG5Bb0dCQUwwdkhRenp6MGRyMzZoTGNRSUEKWmxVaUJSb2UzVERYQUhraWZLYllqMDFJQUErOW9VdXZWNGRQOWRBZnluS1hCR2NQbk9Kc0ZwQzdFN3prRnNtbgp0UmpHdkp6VnRCRGxxVXQzbEdKOEFSMHVzdmdUR3ltdytOSTY5VHBrM3BDRGs3bURLMndZdHZpUFpkUmU0alV4CnI4cDBpa1pvUjhrU0xrSnRmQVNzb1pKUEFvR0FWSTk4bjNrR082WnVxT3FqYkVMd2RTRWJZQkdCYlp1aW8wejAKRm5qZWllU0R0d2c5NzlEUnNrcGxmWXRmZGJ2cG1jT25lbms1a3lvaVhPLzhBMEFSZkE4U1FsUGViRjlIWjY5MApnaDEyN2p3R0hPRURneS9vSFhoMlVQeWgyam42SUZlUFQrYUxFdnB4S0I3S0NCTkJvc1E3M1dUUjVldWpVWTN6CkN3SSt3SVVDZ1lFQXJVQ0k4cng3MVd4S3A0dnNObTJpM2JlT3lYa3dVaFhKUmhmL0cwZk5vc2FhT0RvVEdNT1oKVlRRci9hVWJlQ2pWMlZENTEyVkJEQlZnYUNnZ1ZZS3pSMXpJSDFlMXZzVjhQVjN1Snh0Q2FLT3daTHV4OS9HQQp0QzJOKzFTY05GWkxtU3Z0MzU2WG5EL3VwRUcyeVMydmFURDU1K3FVUlVFWk1TWDlPdFpSL2JBPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
+kind: Secret
+metadata:
+ name: static-file-server-tls
+type: kubernetes.io/tls
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: static-file-server
+spec:
+ selector:
+ app: static-file-server
+ ports:
+ - protocol: TCP
+ port: 443
+ targetPort: 8443
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: static-file-server
+ labels:
+ app: static-file-server
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: static-file-server
+ template:
+ metadata:
+ labels:
+ app: static-file-server
+ spec:
+ containers:
+ - name: static-file-server
+ image: envoyproxy/gateway-static-file-server
+ imagePullPolicy: IfNotPresent
+ args:
+ - "--certPath=/app/certs"
+ - "--port=8443"
+ volumeMounts:
+ - name: secret-volume
+ mountPath: /app/certs
+ volumes:
+ - name: secret-volume
+ secret:
+ secretName: static-file-server-tls
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+ name: static-file-server
+spec:
+ targetRefs:
+ - group: ""
+ kind: Service
+ name: static-file-server
+ sectionName: "443"
+ validation:
+ caCertificateRefs:
+ - name: backend-tls-checks-certificate
+ group: ""
+ kind: ConfigMap
+ hostname: example.com
+---
+apiVersion: v1
+data:
+ ca.crt: |
+ -----BEGIN CERTIFICATE-----
+ MIIDQzCCAiugAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMRMwEQYDVQQKEwpFbnZv
+ eVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBHYXRld2F5
+ IENBMCAXDTI0MDMxMDE1MzIxN1oYDzIxMjQwMzEwMTYzMjE3WjBCMRMwEQYDVQQK
+ EwpFbnZveVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBH
+ YXRld2F5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7ZFmGB4e
+ m1KdGEohAZBfqydAEGLDHJ1YyfHWdd+vBAevdW64bZx3pggJOtgCnePuFd02rDQS
+ dlsJlX/6mFtoQilo6wvxDSJRfaTDbtfTjw+7k8yfd/Jsmh0RWG+UeyI7Na9sXAz7
+ b57mpxsCoNowzeK5ETiOGGNWPcjENJkSnBarz5muN00xIZWBU+yN5PLJNxZvxpZJ
+ Ol/SSI8sno0e0PxAmp3fe7QaXiZj/TAGJPGuTJkUxrHqyZGJtYUxsS8A0dT1zBjj
+ izA5Dp+b5yzYo23Hh7BgpbZ7X4gsDThFuwCD6fHyepuv2zHPqvSsdqg2hAhDp91R
+ zrn7a9GxG2VSIwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
+ AwEB/zAdBgNVHQ4EFgQUUpP1aZ1M2KIuPPWrNPDV2c5CngowDQYJKoZIhvcNAQEL
+ BQADggEBAGSEkAVz+Z0qS4FmA0q4SCpIIq64bsdEjiUzev7pK1LEK0/Y28QBPixV
+ cUXfax18VPR9pls1JgXto9qY+C0hnRZic6611QTJlWK1p6dinQ/eDdYCBC+nv5xx
+ ssASwmplIxMvj3S1qF6dr7sMI2ZVD5HElTWdO19UBLyhiKKZW2KxDsYj+5NRwGFe
+ G+JuDgq7njUM8mdyYk0NehefdBUEUUCQtnwUtW95/429XwqQROuRDteGT9kjD+Y5
+ ea5mW4mfqLeuGJXZs9bdWjKKdLQPrn9IshPysWqz2Hz8dQ1f7N9/g8UWVSjd4cyx
+ S5EAolzVv0yB7wHCWCgfG/ckdOTUNnE=
+ -----END CERTIFICATE-----
+kind: ConfigMap
+metadata:
+ name: backend-tls-checks-certificate
diff --git a/go.mod b/go.mod
index 1231fc39ee8..65bc4067247 100644
--- a/go.mod
+++ b/go.mod
@@ -1,295 +1,291 @@
module github.com/envoyproxy/gateway
-go 1.22.5
+go 1.23.3
replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16
require (
- fortio.org/fortio v1.66.0
- fortio.org/log v1.15.0
- github.com/Masterminds/semver/v3 v3.2.1
- github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b
+ fortio.org/fortio v1.68.0
+ fortio.org/log v1.17.1
+ github.com/Masterminds/semver/v3 v3.3.1
+ github.com/cenkalti/backoff/v4 v4.3.0
+ github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
- github.com/docker/cli v27.0.3+incompatible
+ github.com/docker/cli v27.4.1+incompatible
+ github.com/docker/docker v27.4.1+incompatible
github.com/dominikbraun/graph v0.23.0
- github.com/envoyproxy/go-control-plane v0.12.1-0.20240612043845-c54ec4ce422d
+ github.com/envoyproxy/go-control-plane v0.13.1
github.com/envoyproxy/ratelimit v1.4.1-0.20230427142404-e2a87f41d3a7
+ github.com/evanphx/json-patch v5.9.0+incompatible
github.com/evanphx/json-patch/v5 v5.9.0
- github.com/fatih/color v1.17.0
+ github.com/fatih/color v1.18.0
+ github.com/fsnotify/fsnotify v1.8.0
github.com/go-logfmt/logfmt v0.6.0
github.com/go-logr/logr v1.4.2
github.com/go-logr/zapr v1.3.0
- github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.4
- github.com/google/cel-go v0.20.1
+ github.com/google/cel-go v0.22.1
github.com/google/go-cmp v0.6.0
- github.com/google/go-containerregistry v0.20.1
- github.com/grafana/tempo v1.5.0
+ github.com/google/go-containerregistry v0.20.2
github.com/hashicorp/go-multierror v1.1.1
- github.com/miekg/dns v1.1.61
- github.com/prometheus/client_golang v1.19.1
- github.com/prometheus/common v0.55.0
+ github.com/miekg/dns v1.1.62
+ github.com/ohler55/ojg v1.25.0
+ github.com/pkg/errors v0.9.1
+ github.com/prometheus/client_golang v1.20.5
+ github.com/prometheus/client_model v0.6.1
+ github.com/prometheus/common v0.61.0
+ github.com/replicatedhq/troubleshoot v0.107.5
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
- github.com/stretchr/testify v1.9.0
+ github.com/stretchr/testify v1.10.0
github.com/telepresenceio/watchable v0.0.0-20220726211108-9bb86f92afa7
- github.com/tsaarni/certyaml v0.9.3
- go.opentelemetry.io/otel v1.28.0
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0
- go.opentelemetry.io/otel/exporters/prometheus v0.50.0
- go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0
- go.opentelemetry.io/otel/metric v1.28.0
- go.opentelemetry.io/otel/sdk/metric v1.28.0
- go.opentelemetry.io/proto/otlp v1.3.1
+ github.com/tetratelabs/func-e v1.1.5-0.20240822223546-c85a098d5bf0
+ github.com/tsaarni/certyaml v0.10.0
+ go.opentelemetry.io/otel v1.33.0
+ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.33.0
+ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.33.0
+ go.opentelemetry.io/otel/exporters/prometheus v0.55.0
+ go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.33.0
+ go.opentelemetry.io/otel/metric v1.33.0
+ go.opentelemetry.io/otel/sdk v1.33.0
+ go.opentelemetry.io/otel/sdk/metric v1.33.0
+ go.opentelemetry.io/proto/otlp v1.4.0
go.uber.org/zap v1.27.0
- golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
- golang.org/x/sys v0.22.0
- google.golang.org/grpc v1.65.0
- google.golang.org/protobuf v1.34.2
+ golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e
+ golang.org/x/net v0.33.0
+ golang.org/x/sys v0.28.0
+ google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576
+ google.golang.org/grpc v1.69.2
+ google.golang.org/protobuf v1.36.1
gopkg.in/yaml.v3 v3.0.1
- helm.sh/helm/v3 v3.15.3
- k8s.io/api v0.30.3
- k8s.io/apiextensions-apiserver v0.30.3
- k8s.io/apimachinery v0.30.3
- k8s.io/cli-runtime v0.30.3
- k8s.io/client-go v0.30.3
- k8s.io/kubectl v0.30.3
- k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0
- sigs.k8s.io/controller-runtime v0.18.4
- sigs.k8s.io/gateway-api v1.1.0
+ helm.sh/helm/v3 v3.16.4
+ k8s.io/api v0.32.0
+ k8s.io/apiextensions-apiserver v0.32.0
+ k8s.io/apimachinery v0.32.0
+ k8s.io/cli-runtime v0.32.0
+ k8s.io/client-go v0.32.0
+ k8s.io/klog/v2 v2.130.1
+ k8s.io/kubectl v0.32.0
+ k8s.io/utils v0.0.0-20241210054802-24370beab758
+ sigs.k8s.io/controller-runtime v0.19.3
+ sigs.k8s.io/gateway-api v1.2.1
+ sigs.k8s.io/kubectl-validate v0.0.5-0.20241223122011-eb064d2f92d5
sigs.k8s.io/mcs-api v0.1.0
sigs.k8s.io/yaml v1.4.0
)
require (
- github.com/docker/docker v27.0.3+incompatible
- github.com/replicatedhq/troubleshoot v0.95.1
-)
-
-require (
- cel.dev/expr v0.15.0 // indirect
- cloud.google.com/go v0.112.1 // indirect
- cloud.google.com/go/compute/metadata v0.3.0 // indirect
- cloud.google.com/go/iam v1.1.7 // indirect
- cloud.google.com/go/storage v1.40.0 // indirect
- dario.cat/mergo v1.0.0 // indirect
+ cel.dev/expr v0.18.0 // indirect
+ dario.cat/mergo v1.0.1 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
- fortio.org/cli v1.7.0 // indirect
- fortio.org/dflag v1.7.2 // indirect
- fortio.org/scli v1.15.1 // indirect
- fortio.org/sets v1.1.1 // indirect
+ fortio.org/cli v1.9.2 // indirect
+ fortio.org/dflag v1.7.3 // indirect
+ fortio.org/safecast v1.0.0 // indirect
+ fortio.org/scli v1.15.3 // indirect
+ fortio.org/sets v1.2.0 // indirect
fortio.org/struct2env v0.4.1 // indirect
fortio.org/version v1.0.4 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
+ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/BurntSushi/toml v1.4.0 // indirect
+ github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
- github.com/Masterminds/sprig/v3 v3.2.3 // indirect
+ github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
- github.com/Microsoft/hcsshim v0.12.3 // indirect
+ github.com/Microsoft/hcsshim v0.12.5 // indirect
+ github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/apparentlymart/go-cidr v1.1.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
- github.com/aws/aws-sdk-go v1.48.10 // indirect
- github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
+ github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/c9s/goprocinfo v0.0.0-20170724085704-0010a05ce49f // indirect
+ github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
+ github.com/chai2010/gettext-go v1.0.2 // indirect
+ github.com/cilium/ebpf v0.16.0 // indirect
github.com/containerd/cgroups/v3 v3.0.3 // indirect
- github.com/containerd/containerd v1.7.17 // indirect
- github.com/containerd/errdefs v0.1.0 // indirect
+ github.com/containerd/containerd v1.7.23 // indirect
+ github.com/containerd/errdefs v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
+ github.com/containerd/platforms v0.2.1 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
- github.com/containers/image/v5 v5.31.1 // indirect
+ github.com/containers/image/v5 v5.32.2 // indirect
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
- github.com/containers/ocicrypt v1.1.10 // indirect
- github.com/containers/storage v1.54.0 // indirect
- github.com/cyphar/filepath-securejoin v0.2.5 // indirect
- github.com/distribution/distribution/v3 v3.0.0-alpha.1 // indirect
+ github.com/containers/ocicrypt v1.2.0 // indirect
+ github.com/containers/storage v1.55.0 // indirect
+ github.com/coreos/go-semver v0.3.1 // indirect
+ github.com/coreos/go-systemd/v22 v22.5.0 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
+ github.com/cyphar/filepath-securejoin v0.3.4 // indirect
+ github.com/distribution/distribution/v3 v3.0.0-beta.1 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.5.0 // indirect
+ github.com/emicklei/go-restful/v3 v3.12.0 // indirect
+ github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
+ github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
+ github.com/fxamacker/cbor/v2 v2.7.0 // indirect
+ github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
+ github.com/go-errors/errors v1.4.2 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
+ github.com/go-openapi/jsonpointer v0.21.0 // indirect
+ github.com/go-openapi/jsonreference v0.21.0 // indirect
+ github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-redis/redis/v7 v7.4.1 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
+ github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
+ github.com/google/btree v1.0.1 // indirect
+ github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-intervals v0.0.2 // indirect
- github.com/google/s2a-go v0.1.7 // indirect
- github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
- github.com/googleapis/gax-go/v2 v2.12.3 // indirect
+ github.com/google/gofuzz v1.2.0 // indirect
+ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
+ github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/handlers v1.5.2 // indirect
github.com/gorilla/mux v1.8.1 // indirect
+ github.com/gorilla/websocket v1.5.1 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
+ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
+ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
- github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
- github.com/hashicorp/go-getter v1.7.5 // indirect
- github.com/hashicorp/go-safetemp v1.0.0 // indirect
- github.com/hashicorp/go-version v1.7.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
- github.com/huandu/xstrings v1.4.0 // indirect
+ github.com/huandu/xstrings v1.5.0 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
- github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
- github.com/jackc/pgx/v5 v5.6.0 // indirect
- github.com/jmespath/go-jmespath v0.4.0 // indirect
- github.com/jmoiron/sqlx v1.3.5 // indirect
- github.com/klauspost/compress v1.17.8 // indirect
+ github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
+ github.com/jackc/pgx/v5 v5.7.1 // indirect
+ github.com/jmoiron/sqlx v1.4.0 // indirect
+ github.com/josharian/intern v1.0.0 // indirect
+ github.com/json-iterator/go v1.1.12 // indirect
+ github.com/kelseyhightower/envconfig v1.4.0 // indirect
+ github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/kortschak/goroutine v1.1.2 // indirect
+ github.com/kylelemons/godebug v1.1.0 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lib/pq v1.10.9 // indirect
+ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/longhorn/go-iscsi-helper v0.0.0-20210330030558-49a327fb024e // indirect
- github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
+ github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect
+ github.com/lyft/gostats v0.4.1 // indirect
github.com/magiconair/properties v1.8.7 // indirect
+ github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
- github.com/mattn/go-runewidth v0.0.15 // indirect
+ github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/microsoft/go-mssqldb v1.7.2 // indirect
github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
- github.com/mitchellh/go-testing-interface v1.14.1 // indirect
+ github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
- github.com/moby/sys/mountinfo v0.7.1 // indirect
+ github.com/moby/spdystream v0.5.0 // indirect
+ github.com/moby/sys/mountinfo v0.7.2 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
- github.com/moby/sys/user v0.1.0 // indirect
+ github.com/moby/sys/user v0.3.0 // indirect
+ github.com/moby/sys/userns v0.1.0 // indirect
+ github.com/moby/term v0.5.0 // indirect
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+ github.com/modern-go/reflect2 v1.0.2 // indirect
+ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
+ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
github.com/opencontainers/selinux v1.11.0 // indirect
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
+ github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
- github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
+ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+ github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
+ github.com/prometheus/procfs v0.15.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
- github.com/rubenv/sql-migrate v1.6.1 // indirect
+ github.com/rubenv/sql-migrate v1.7.0 // indirect
+ github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/segmentio/ksuid v1.0.4 // indirect
github.com/shirou/gopsutil/v3 v3.24.5 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
+ github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
- github.com/spf13/cast v1.6.0 // indirect
+ github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/viper v1.19.0 // indirect
- github.com/stoewer/go-strcase v1.2.0 // indirect
+ github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
- github.com/sylabs/sif/v2 v2.16.0 // indirect
+ github.com/sylabs/sif/v2 v2.18.0 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
+ github.com/tsaarni/x500dn v1.0.0 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
+ github.com/urfave/cli/v2 v2.8.1 // indirect
github.com/vbatts/tar-split v0.11.5 // indirect
- github.com/vmware-tanzu/velero v1.14.0 // indirect
+ github.com/x448/float16 v0.8.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
+ github.com/xlab/treeprint v1.2.0 // indirect
+ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
+ go.etcd.io/etcd/api/v3 v3.5.16 // indirect
+ go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect
+ go.etcd.io/etcd/client/v3 v3.5.16 // indirect
go.opencensus.io v0.24.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
- golang.org/x/crypto v0.25.0 // indirect
- golang.org/x/crypto/x509roots/fallback v0.0.0-20240626151235-a6a393ffd658 // indirect
- google.golang.org/api v0.172.0 // indirect
- google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
- gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
- gopkg.in/ini.v1 v1.67.0 // indirect
- k8s.io/apiserver v0.30.3 // indirect
- k8s.io/kubelet v0.30.2 // indirect
- k8s.io/metrics v0.30.3 // indirect
- oras.land/oras-go v1.2.5 // indirect
- periph.io/x/host/v3 v3.8.2 // indirect
-)
-
-require (
- github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
- github.com/MakeNowJust/heredoc v1.0.0 // indirect
- github.com/beorn7/perks v1.0.1 // indirect
- github.com/cenkalti/backoff/v4 v4.3.0
- github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
- github.com/cespare/xxhash/v2 v2.3.0 // indirect
- github.com/chai2010/gettext-go v1.0.3 // indirect
- github.com/emicklei/go-restful/v3 v3.12.1 // indirect
- github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
- github.com/evanphx/json-patch v5.9.0+incompatible
- github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
- github.com/fsnotify/fsnotify v1.7.0 // indirect
- github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
- github.com/go-errors/errors v1.5.1 // indirect
- github.com/go-logr/stdr v1.2.2 // indirect
- github.com/go-openapi/jsonpointer v0.21.0 // indirect
- github.com/go-openapi/jsonreference v0.21.0 // indirect
- github.com/go-openapi/swag v0.23.0 // indirect
- github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
- github.com/google/btree v1.1.2 // indirect
- github.com/google/gnostic-models v0.6.8 // indirect
- github.com/google/gofuzz v1.2.0 // indirect
- github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
- github.com/google/uuid v1.6.0 // indirect
- github.com/gorilla/websocket v1.5.1 // indirect
- github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
- github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
- github.com/imdario/mergo v1.0.0 // indirect
- github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/josharian/intern v1.0.0 // indirect
- github.com/json-iterator/go v1.1.12 // indirect
- github.com/kelseyhightower/envconfig v1.4.0 // indirect
- github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
- github.com/lyft/gostats v0.4.14 // indirect
- github.com/mailru/easyjson v0.7.7 // indirect
- github.com/mitchellh/go-wordwrap v1.0.1 // indirect
- github.com/moby/spdystream v0.2.0 // indirect
- github.com/moby/term v0.5.0 // indirect
- github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
- github.com/modern-go/reflect2 v1.0.2 // indirect
- github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
- github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
- github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
- github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
- github.com/pkg/errors v0.9.1
- github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
- github.com/prometheus/client_model v0.6.1
- github.com/prometheus/procfs v0.15.1 // indirect
- github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/sirupsen/logrus v1.9.3 // indirect
- github.com/tsaarni/x500dn v1.0.0 // indirect
- github.com/xlab/treeprint v1.2.0 // indirect
- go.opentelemetry.io/otel/sdk v1.28.0
- go.opentelemetry.io/otel/trace v1.28.0 // indirect
- go.starlark.net v0.0.0-20240520160348-046347dcd104 // indirect
+ go.opentelemetry.io/auto/sdk v1.1.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
+ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
+ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect
+ go.opentelemetry.io/otel/trace v1.33.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
- golang.org/x/mod v0.18.0 // indirect
- golang.org/x/net v0.27.0
- golang.org/x/oauth2 v0.21.0 // indirect
- golang.org/x/sync v0.7.0 // indirect
- golang.org/x/term v0.22.0 // indirect
- golang.org/x/text v0.16.0 // indirect
- golang.org/x/time v0.5.0 // indirect
- golang.org/x/tools v0.22.0 // indirect
+ golang.org/x/crypto v0.31.0 // indirect
+ golang.org/x/crypto/x509roots/fallback v0.0.0-20240904212608-c9da6b9a4008 // indirect
+ golang.org/x/mod v0.21.0 // indirect
+ golang.org/x/oauth2 v0.24.0 // indirect
+ golang.org/x/sync v0.10.0 // indirect
+ golang.org/x/term v0.27.0 // indirect
+ golang.org/x/text v0.21.0 // indirect
+ golang.org/x/time v0.7.0 // indirect
+ golang.org/x/tools v0.26.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
+ gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
+ gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
- k8s.io/component-base v0.30.3 // indirect
- k8s.io/klog/v2 v2.130.1 // indirect
- k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a // indirect
- sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
- sigs.k8s.io/kustomize/api v0.17.2 // indirect
- sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect
- sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
+ k8s.io/apiserver v0.32.0 // indirect
+ k8s.io/component-base v0.32.0 // indirect
+ k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect
+ k8s.io/metrics v0.32.0 // indirect
+ oras.land/oras-go v1.2.6 // indirect
+ periph.io/x/host/v3 v3.8.2 // indirect
+ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.1 // indirect
+ sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
+ sigs.k8s.io/kustomize/api v0.18.0 // indirect
+ sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect
+ sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect
)
diff --git a/go.sum b/go.sum
index 259c15915b6..058e8e6d983 100644
--- a/go.sum
+++ b/go.sum
@@ -1,208 +1,28 @@
-cel.dev/expr v0.15.0 h1:O1jzfJCQBfL5BFoYktaxwIhuttaQPsVWerH9/EEKx0w=
-cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=
+cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo=
+cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
-cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
-cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
-cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
-cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
-cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
-cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
-cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
-cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
-cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
-cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
-cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
-cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
-cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
-cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
-cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
-cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
-cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
-cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
-cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
-cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
-cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
-cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
-cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
-cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
-cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
-cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
-cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
-cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
-cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
-cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
-cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw=
-cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY=
-cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=
-cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4=
-cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4=
-cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0=
-cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ=
-cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk=
-cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o=
-cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s=
-cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0=
-cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY=
-cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw=
-cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI=
-cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0=
-cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8=
-cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
-cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
-cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
-cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
-cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
-cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA=
-cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY=
-cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s=
-cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM=
-cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI=
-cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY=
-cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI=
-cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
-cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
-cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
-cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
-cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
-cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
-cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=
-cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
-cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
-cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I=
-cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4=
-cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0=
-cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs=
-cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc=
-cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM=
-cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ=
-cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo=
-cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE=
-cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I=
-cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ=
-cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo=
-cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA=
-cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
-cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo=
-cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ=
-cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4=
-cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0=
-cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8=
-cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU=
-cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU=
-cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y=
-cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg=
-cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk=
-cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w=
-cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk=
-cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg=
-cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM=
-cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA=
-cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o=
-cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A=
-cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0=
-cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0=
-cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc=
-cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
-cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc=
-cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM=
-cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA=
-cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=
-cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=
-cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8=
-cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08=
-cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4=
-cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w=
-cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE=
-cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM=
-cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY=
-cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s=
-cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA=
-cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o=
-cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ=
-cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU=
-cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY=
-cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34=
-cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs=
-cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg=
-cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E=
-cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU=
-cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0=
-cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA=
-cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0=
-cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI=
-cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
-cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
-cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
-cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4=
-cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o=
-cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk=
-cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo=
-cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg=
-cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4=
-cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg=
-cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c=
-cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y=
-cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A=
-cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4=
-cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY=
-cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s=
-cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI=
-cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA=
-cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4=
-cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0=
-cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU=
-cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU=
-cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc=
-cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs=
-cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg=
-cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM=
-cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ=
-cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
-cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
-cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
-cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
-cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
-cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
-cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc=
-cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s=
-cloud.google.com/go/storage v1.40.0 h1:VEpDQV5CJxFmJ6ueWNsKxcr1QAYOXEgxDa+sBbJahPw=
-cloud.google.com/go/storage v1.40.0/go.mod h1:Rrj7/hKlG87BLqDJYtwR0fbPld8uJPbQ2ucUMY7Ir0g=
-cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw=
-cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g=
-cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU=
-cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4=
-cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0=
-cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo=
-cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo=
-cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE=
-cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=
-cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
-cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
-dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
-dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
-dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
+dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
fortio.org/assert v1.2.1 h1:48I39urpeDj65RP1KguF7akCjILNeu6vICiYMEysR7Q=
fortio.org/assert v1.2.1/go.mod h1:039mG+/iYDPO8Ibx8TrNuJCm2T2SuhwRI3uL9nHTTls=
-fortio.org/cli v1.7.0 h1:w+uXZLGi4t3Vn/BvbeMuSw84Z1pvNPG9HqeGfpP68cc=
-fortio.org/cli v1.7.0/go.mod h1:s4vxWz7P7T4cYOWdMF0NA693Nu1gK9OW4KoDj54/Do4=
-fortio.org/dflag v1.7.2 h1:lUhXFvDlw4CJj/q7hPv/TC+n/wVoQylzQO6bUg5GQa0=
-fortio.org/dflag v1.7.2/go.mod h1:6yO/NIgrWfQH195WbHJ3Y45SCx11ffivQjfx2C/FS1U=
-fortio.org/fortio v1.66.0 h1:9F/200qIu136z847bxs/NeAoYdJaQlVofYlppi3qwcw=
-fortio.org/fortio v1.66.0/go.mod h1:eUl5MRscw6CiWAStai8aB3/8unxA9uNzJRXdhKEaq1s=
-fortio.org/log v1.15.0 h1:DRbZzgZH4av3ZPz6yIcvBwMy4NLH8a5iznRXXEegvJQ=
-fortio.org/log v1.15.0/go.mod h1:t58Spg9njjymvRioh5F6qKGSupEsnMjXLGWIS1i3khE=
-fortio.org/scli v1.15.1 h1:Upza50brpEZwUk8Nn2gdP4BjgqJZY3J+z7KLrrAzPjY=
-fortio.org/scli v1.15.1/go.mod h1:9LOD4iPe9u73KeJGYC/Af1oFniOafO7oZ9VvwENMf/c=
-fortio.org/sets v1.1.1 h1:Q7Z1Ft2lpUc1N7bfI8HofIK0QskrOflfYRyKT2LzBng=
-fortio.org/sets v1.1.1/go.mod h1:J2BwIxNOLWsSU7IMZUg541kh3Au4JEKHrghVwXs68tE=
+fortio.org/cli v1.9.2 h1:17eJ8QZPjXHcLBpeCe0QMO/0fj5Bw0ZTxVgL7V9jOqc=
+fortio.org/cli v1.9.2/go.mod h1:7r55OoTV8NXcTvJT4boWk8s3I2LP6TMZh/0LLMJEYw0=
+fortio.org/dflag v1.7.3 h1:yws+v+/fJ67bYgrgcWpLtgdZPEWkYuwdfqz/WyQ8UXo=
+fortio.org/dflag v1.7.3/go.mod h1:O1Pk4lKRolw9wwAGyjTo8IsNyqqNRQGKxPOfpOElMqM=
+fortio.org/fortio v1.68.0 h1:2M9RuitiN+MgW6QlTJCHjW6PJLAPj/YCXegxSCLQ3rw=
+fortio.org/fortio v1.68.0/go.mod h1:1IjDaEoT5crHBN7BRLBwrHE24pIT6rOPKrYG3jEIWaA=
+fortio.org/log v1.17.1 h1:YQoGyZBnXTVIs77/nZw7BppwSOIamP3I092PGBenBZs=
+fortio.org/log v1.17.1/go.mod h1:t58Spg9njjymvRioh5F6qKGSupEsnMjXLGWIS1i3khE=
+fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY=
+fortio.org/safecast v1.0.0/go.mod h1:xZmcPk3vi4kuUFf+tq4SvnlVdwViqf6ZSZl91Jr9Jdg=
+fortio.org/scli v1.15.3 h1:XZYONPupGOd1Q68G4aq0vWg9obw0M57sC4snkyiab9w=
+fortio.org/scli v1.15.3/go.mod h1:cWJJbXObkF+GsbtPqxE60GFctllOANYS+Yp9PJK0xK8=
+fortio.org/sets v1.2.0 h1:FBfC7R2xrOJtkcioUbY6WqEzdujuBoZRbSdp1fYF4Kk=
+fortio.org/sets v1.2.0/go.mod h1:J2BwIxNOLWsSU7IMZUg541kh3Au4JEKHrghVwXs68tE=
fortio.org/struct2env v0.4.1 h1:rJludAMO5eBvpWplWEQNqoVDFZr4RWMQX7RUapgZyc0=
fortio.org/struct2env v0.4.1/go.mod h1:lENUe70UwA1zDUCX+8AsO663QCFqYaprk5lnPhjD410=
fortio.org/version v1.0.4 h1:FWUMpJ+hVTNc4RhvvOJzb0xesrlRmG/a+D6bjbQ4+5U=
@@ -213,10 +33,10 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
-github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 h1:FDif4R1+UUR+00q6wquyX90K7A8dN+R5E8GEadoP7sU=
-github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2/go.mod h1:aiYBYui4BJ/BJCAIKs92XiPyQfTaBWqvHujDwKb6CBU=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 h1:jBQA3cKT4L2rWMpgE7Yt3Hwh2aUj8KXjIGLxjHeYNNo=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 h1:MyVTgWR8qd/Jw1Le0NZebGBUCLbtak3bJ3z1OlqZBpw=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1/go.mod h1:GpPjLhVR9dnUoJMyHWSPy71xY9/lcmpzIPZXmF0FCVY=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80=
@@ -236,25 +56,25 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
-github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
-github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
-github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
-github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
-github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
+github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
+github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
+github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
+github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
-github.com/Microsoft/hcsshim v0.12.3 h1:LS9NXqXhMoqNCplK1ApmVSfB4UnVLRDWRapB6EIlxE0=
-github.com/Microsoft/hcsshim v0.12.3/go.mod h1:Iyl1WVpZzr+UkzjekHZbV8o5Z9ZkxNGx6CtY2Qg/JVQ=
+github.com/Microsoft/hcsshim v0.12.5 h1:bpTInLlDy/nDRWFVcefDZZ1+U8tS+rz3MxjKgu9boo0=
+github.com/Microsoft/hcsshim v0.12.5/go.mod h1:tIUGego4G1EN5Hb6KC90aDYiUI2dqLSTTOCjVNpOgZ8=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
+github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
+github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
@@ -266,7 +86,6 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alessio/shellescape v1.2.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
-github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
@@ -278,15 +97,10 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
-github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
-github.com/aws/aws-sdk-go v1.48.10 h1:0LIFG3wp2Dt6PsxKWCg1Y1xRrn2vZnW5/gWdgaBalKg=
-github.com/aws/aws-sdk-go v1.48.10/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
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/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
-github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
@@ -301,57 +115,49 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
-github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/chai2010/gettext-go v1.0.3 h1:9liNh8t+u26xl5ddmWLmsOsdNLwkdRTg5AG+JnTiM80=
-github.com/chai2010/gettext-go v1.0.3/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
-github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
-github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
-github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
-github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
+github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
+github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok=
+github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
-github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw=
-github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI=
+github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
-github.com/containerd/containerd v1.7.17 h1:KjNnn0+tAVQHAoaWRjmdak9WlvnFR/8rU1CHHy8Rm2A=
-github.com/containerd/containerd v1.7.17/go.mod h1:vK+hhT4TIv2uejlcDlbVIc8+h/BqtKLIyNrtCZol8lI=
+github.com/containerd/containerd v1.7.23 h1:H2CClyUkmpKAGlhQp95g2WXHfLYc7whAuvZGBNYOOwQ=
+github.com/containerd/containerd v1.7.23/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw=
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
-github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
-github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
+github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
+github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
+github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
+github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
-github.com/containers/image/v5 v5.31.1 h1:3x9soI6Biml/GiDLpkSmKrkRSwVGctxu/vONpoUdklA=
-github.com/containers/image/v5 v5.31.1/go.mod h1:5QfOqSackPkSbF7Qxc1DnVNnPJKQ+KWLkfEfDpK590Q=
+github.com/containers/image/v5 v5.32.2 h1:SzNE2Y6sf9b1GJoC8qjCuMBXwQrACFp4p0RK15+4gmQ=
+github.com/containers/image/v5 v5.32.2/go.mod h1:v1l73VeMugfj/QtKI+jhYbwnwFCFnNGckvbST3rQ5Hk=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
-github.com/containers/ocicrypt v1.1.10 h1:r7UR6o8+lyhkEywetubUUgcKFjOWOaWz8cEBrCPX0ic=
-github.com/containers/ocicrypt v1.1.10/go.mod h1:YfzSSr06PTHQwSTUKqDSjish9BeW1E4HUmreluQcMd8=
-github.com/containers/storage v1.54.0 h1:xwYAlf6n9OnIlURQLLg3FYHbO74fQ/2W2N6EtQEUM4I=
-github.com/containers/storage v1.54.0/go.mod h1:PlMOoinRrBSnhYODLxt4EXl0nmJt+X0kjG0Xdt9fMTw=
+github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sirVuPM=
+github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U=
+github.com/containers/storage v1.55.0 h1:wTWZ3YpcQf1F+dSP4KxG9iqDfpQY1otaUXjPpffuhgg=
+github.com/containers/storage v1.55.0/go.mod h1:28cB81IDk+y7ok60Of6u52RbCeBRucbFOeLunhER1RQ=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
+github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
@@ -359,12 +165,13 @@ github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfc
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
-github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo=
-github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
+github.com/cyphar/filepath-securejoin v0.3.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8=
+github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM=
github.com/datawire/dlib v1.3.0 h1:KkmyXU1kwm3oPBk1ypR70YbcOlEXWzEbx5RE0iRXTGk=
github.com/datawire/dlib v1.3.0/go.mod h1:NiGDmetmbkBvtznpWSx6C0vA0s0LK9aHna3LJDqjruk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -375,17 +182,17 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
-github.com/distribution/distribution/v3 v3.0.0-alpha.1 h1:jn7I1gvjOvmLztH1+1cLiUFud7aeJCIQcgzugtwjyJo=
-github.com/distribution/distribution/v3 v3.0.0-alpha.1/go.mod h1:LCp4JZp1ZalYg0W/TN05jarCQu+h4w7xc7ZfQF4Y/cY=
+github.com/distribution/distribution/v3 v3.0.0-beta.1 h1:X+ELTxPuZ1Xe5MsD3kp2wfGUhc8I+MPfRis8dZ818Ic=
+github.com/distribution/distribution/v3 v3.0.0-beta.1/go.mod h1:O9O8uamhHzWWQVTjuQpyYUVm/ShPHPUDgvQMpHGVBDs=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
-github.com/docker/cli v27.0.3+incompatible h1:usGs0/BoBW8MWxGeEtqPMkzOY56jZ6kYlSN5BLDioCQ=
-github.com/docker/cli v27.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/cli v27.4.1+incompatible h1:VzPiUlRJ/xh+otB75gva3r05isHMo5wXDfPRi5/b4hI=
+github.com/docker/cli v27.4.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v27.0.3+incompatible h1:aBGI9TeQ4MPlhquTQKq9XbK79rKFVwXNUAYz9aXyEBE=
-github.com/docker/docker v27.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v27.4.1+incompatible h1:ZJvcY7gfwHn1JF48PfbyXg7Jyt9ZCWDW+GGXOIxEwp4=
+github.com/docker/docker v27.4.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
@@ -406,25 +213,21 @@ github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucV
github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU=
-github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk=
+github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
-github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
-github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
-github.com/envoyproxy/go-control-plane v0.12.1-0.20240612043845-c54ec4ce422d h1:RopQsG28t61pLLZRkwzwBsi60yDsOP8RvW47A3eAcGo=
-github.com/envoyproxy/go-control-plane v0.12.1-0.20240612043845-c54ec4ce422d/go.mod h1:5Wkq+JduFtdAXihLmeTJf+tRYIT4KBc2vPXDhwVo1pA=
+github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
+github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
-github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
+github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
+github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
github.com/envoyproxy/ratelimit v1.4.1-0.20230427142404-e2a87f41d3a7 h1:yz9/p/8QVPuEjPqRfZDXJmRaURKpKkxCZXUhl22i+cU=
github.com/envoyproxy/ratelimit v1.4.1-0.20230427142404-e2a87f41d3a7/go.mod h1:NmJBO+gDMvSQWvcSWq8wmlgkDmHHAkx1SCxEGva5hKU=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
@@ -437,29 +240,28 @@ github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4=
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
-github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
+github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
+github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
-github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI=
-github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4=
+github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI=
+github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
-github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
+github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
+github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
+github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
-github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
-github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
-github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
+github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@@ -528,18 +330,19 @@ github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
+github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
+github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/go-redis/redis/v7 v7.4.1 h1:PASvf36gyUpr2zdOUS/9Zqc80GbM+9BDyiJSJDDOrTI=
github.com/go-redis/redis/v7 v7.4.1/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
-github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -547,6 +350,8 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
@@ -556,27 +361,15 @@ github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EO
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
-github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
+github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
-github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
-github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
-github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@@ -585,100 +378,49 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
-github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
-github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84=
-github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg=
-github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
-github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
+github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
+github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
+github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40=
+github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
+github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
+github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
-github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-containerregistry v0.20.1 h1:eTgx9QNYugV4DN5mz4U8hiAGTi1ybXn0TPi4Smd8du0=
-github.com/google/go-containerregistry v0.20.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
+github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo=
+github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8=
github.com/google/go-intervals v0.0.2 h1:FGrVEiUnTRKR8yE04qzXYaJMtnIYqobR5QbblK3ixcM=
github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
-github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
-github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
-github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
-github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
-github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg=
-github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
-github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
+github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
+github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
-github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
-github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
-github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
-github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
-github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
-github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
-github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
-github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
-github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
-github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo=
-github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY=
-github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA=
-github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
-github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
@@ -686,38 +428,30 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=
github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
-github.com/grafana/tempo v1.5.0 h1:JSwulLVtXvUw2MyuUPcvRg3MJiwTUs5XWnbG6fOKatc=
-github.com/grafana/tempo v1.5.0/go.mod h1:IB52YU6zkGL+3t0eNrY8kAExx0lLa4LH20wGu3c4wD8=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
+github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
-github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
-github.com/hashicorp/go-getter v1.7.5 h1:dT58k9hQ/vbxNMwoI5+xFYAJuv6152UNvdHokfI5wE4=
-github.com/hashicorp/go-getter v1.7.5/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744=
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-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
-github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
-github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
-github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
@@ -729,36 +463,34 @@ github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
-github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
+github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
+github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
-github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
-github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY=
-github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw=
-github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
-github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
+github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
+github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
+github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
-github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
-github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
-github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
-github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
-github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
+github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
+github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
+github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
+github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
+github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM=
+github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -766,7 +498,6 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
-github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
@@ -774,9 +505,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
-github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
-github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
+github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -797,7 +527,6 @@ github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
-github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
@@ -805,10 +534,10 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9
github.com/longhorn/go-iscsi-helper v0.0.0-20210330030558-49a327fb024e h1:hz4quJkaJWDo+xW+G6wTF6d6/95QvJ+o2D0+bB/tJ1U=
github.com/longhorn/go-iscsi-helper v0.0.0-20210330030558-49a327fb024e/go.mod h1:9z/y9glKmWEdV50tjlUPxFwi1goQfIrrsoZbnMyIZbY=
github.com/longhorn/nsfilelock v0.0.0-20200723175406-fa7c83ad0003/go.mod h1:0CLeXlf59Lg6C0kjLSDf47ft73Dh37CwymYRKWwAn04=
-github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
-github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
-github.com/lyft/gostats v0.4.14 h1:xmP4yMfDvEKtlNZEcS2sYz0cvnps1ri337ZEEbw3ab8=
-github.com/lyft/gostats v0.4.14/go.mod h1:cJWqEVL8JIewIJz/olUIios2F1q06Nc51hXejPQmBH0=
+github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY=
+github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
+github.com/lyft/gostats v0.4.1 h1:oR6p4HRCGxt0nUntmZIWmYMgyothBi3eZH2A71vRjsc=
+github.com/lyft/gostats v0.4.1/go.mod h1:Tpx2xRzz4t+T2Tx0xdVgIoBdR2UMVz+dKnE3X01XSd8=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
@@ -831,32 +560,30 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
-github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
-github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
+github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
+github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
+github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
+github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
-github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
-github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
+github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
+github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
-github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
-github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
@@ -865,14 +592,16 @@ github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
-github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
-github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
-github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
-github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
+github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
+github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
+github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
+github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
-github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
-github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
+github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=
+github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
+github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
+github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -894,9 +623,10 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
+github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
-github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
-github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/ohler55/ojg v1.25.0 h1:sDwc4u4zex65Uz5Nm7O1QwDKTT+YRcpeZQTy1pffRkw=
+github.com/ohler55/ojg v1.25.0/go.mod h1:gQhDVpQLqrmnd2eqGAvJtn+NfKoYJbe/A4Sj3/Vro4o=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -904,18 +634,17 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
-github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
-github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
-github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g=
-github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc=
+github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
+github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
-github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
+github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
+github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
@@ -946,8 +675,8 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
-github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
+github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig=
+github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY=
github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
@@ -955,8 +684,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
-github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
-github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
+github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
+github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -967,8 +696,8 @@ github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7q
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
-github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
-github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ=
+github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
@@ -983,18 +712,16 @@ github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb
github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnAfVjZNvfJTYfPetfZk5yoSTLaQ=
github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY=
github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c=
-github.com/replicatedhq/troubleshoot v0.95.1 h1:r7CQl4WuZrKNjMerG/ljCzHJY43oTQN0fpRP8GcBUEw=
-github.com/replicatedhq/troubleshoot v0.95.1/go.mod h1:ghle+cwNow+SgGMGZ3jRouRbAbT22uVpKbJSxNvNc00=
+github.com/replicatedhq/troubleshoot v0.107.5 h1:XrJEK8vN3HHEKmFnAe8rSmY+hPw8Fh5dsTMhhEBKQCM=
+github.com/replicatedhq/troubleshoot v0.107.5/go.mod h1:QTV4q6TXiCO825IS1GcLzgJu2KHWekXiKdcHCqBJTck=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
-github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
-github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
-github.com/rubenv/sql-migrate v1.6.1 h1:bo6/sjsan9HaXAsNxYP/jCEDUGibHp8JmOBw7NTGRos=
-github.com/rubenv/sql-migrate v1.6.1/go.mod h1:tPzespupJS0jacLfhbwto/UjSX+8h2FdWB7ar+QlHa0=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rubenv/sql-migrate v1.7.0 h1:HtQq1xyTN2ISmQDggnh0c9U3JlP8apWh8YO2jzlXpTI=
+github.com/rubenv/sql-migrate v1.7.0/go.mod h1:S4wtDEG1CKn+0ShpTtzWhFpHHI5PvCUtiGI+C+Z2THE=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
@@ -1016,7 +743,6 @@ github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFt
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
-github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
@@ -1026,6 +752,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
+github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@@ -1034,9 +762,8 @@ github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTd
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
-github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
+github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
+github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
@@ -1052,8 +779,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
-github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
-github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
+github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
+github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
@@ -1064,19 +791,19 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
-github.com/sylabs/sif/v2 v2.16.0 h1:2eqaBaQQsn5DZTzm3QZm0HupZQEjNXfxRnCmtyCihEU=
-github.com/sylabs/sif/v2 v2.16.0/go.mod h1:d5TxgD/mhMUU3kWLmZmWJQ99Wg0asaTP0bq3ezR1xpg=
+github.com/sylabs/sif/v2 v2.18.0 h1:eXugsS1qx7St2Wu/AJ21KnsQiVCpouPlTigABh+6KYI=
+github.com/sylabs/sif/v2 v2.18.0/go.mod h1:GOQj7LIBqp15fjqH5i8ZEbLp8SXJi9S+xbRO+QQAdRo=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
@@ -1085,6 +812,8 @@ github.com/telepresenceio/telepresence/rpc/v2 v2.6.8 h1:q5V85LBT9bA/c4YPa/kMvJGy
github.com/telepresenceio/telepresence/rpc/v2 v2.6.8/go.mod h1:VlgfRoXaW6Tl8IZbHmMWhITne8HY09/wOFtABHGj3ic=
github.com/telepresenceio/watchable v0.0.0-20220726211108-9bb86f92afa7 h1:GMw3nEaOVyi+tNiGko5kAeRtoiEIpXNHmISyZ7fpw14=
github.com/telepresenceio/watchable v0.0.0-20220726211108-9bb86f92afa7/go.mod h1:ihJ97e2gsd8GuzFF/I3B1qcik3XZLpXjumQifXi8Slg=
+github.com/tetratelabs/func-e v1.1.5-0.20240822223546-c85a098d5bf0 h1:+OHaiOveLnsmUMSZT5vxL6rrpy5rcSsfnx9Mogfo1Kk=
+github.com/tetratelabs/func-e v1.1.5-0.20240822223546-c85a098d5bf0/go.mod h1:u78wX1mT5MiSZ3rw8+epQ7fcIT7m83YiwdPT2EWgb0Y=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
@@ -1092,21 +821,24 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/tsaarni/certyaml v0.9.3 h1:m8HHbuUzWVUOmv8IQU9HgVZZ8r5ICExKm++54DJKCs0=
-github.com/tsaarni/certyaml v0.9.3/go.mod h1:hhuU1qYr5re488geArUP4gZWqMUMqGlj4HA2qUyGYLk=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk=
+github.com/tsaarni/certyaml v0.10.0 h1:8ZWHO4Zg4VHUf7YblZNju44PcG5M+YtlJawiArYUHRs=
+github.com/tsaarni/certyaml v0.10.0/go.mod h1:rI1wDTE/VQIglHOyGbjfvqb+5mWTVT5uLFVDDcT1sq8=
github.com/tsaarni/x500dn v1.0.0 h1:LvaWTkqRpse4VHBhB5uwf3wytokK4vF9IOyNAEyiA+U=
github.com/tsaarni/x500dn v1.0.0/go.mod h1:QaHa3EcUKC4dfCAZmj8+ZRGLKukWgpGv9H3oOCsAbcE=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
-github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
+github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
-github.com/vmware-tanzu/velero v1.14.0 h1:ZYy9TLtokdHInIdWTfwHYIZhRr+xLd0nGzHyQrXMCIM=
-github.com/vmware-tanzu/velero v1.14.0/go.mod h1:yeGs7/xq35yOGDPCV0ryxoybQBsTLXmrxwzXBXtiwp8=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -1115,69 +847,79 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk=
+github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
+github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
+go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
+go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
+go.etcd.io/etcd/api/v3 v3.5.16 h1:WvmyJVbjWqK4R1E+B12RRHz3bRGy9XVfh++MgbN+6n0=
+go.etcd.io/etcd/api/v3 v3.5.16/go.mod h1:1P4SlIP/VwkDmGo3OlOD7faPeP8KDIFhqvciH5EfN28=
+go.etcd.io/etcd/client/pkg/v3 v3.5.16 h1:ZgY48uH6UvB+/7R9Yf4x574uCO3jIx0TRDyetSfId3Q=
+go.etcd.io/etcd/client/pkg/v3 v3.5.16/go.mod h1:V8acl8pcEK0Y2g19YlOV9m9ssUe6MgiDSobSoaBAM0E=
+go.etcd.io/etcd/client/v2 v2.305.16 h1:kQrn9o5czVNaukf2A2At43cE9ZtWauOtf9vRZuiKXow=
+go.etcd.io/etcd/client/v2 v2.305.16/go.mod h1:h9YxWCzcdvZENbfzBTFCnoNumr2ax3F19sKMqHFmXHE=
+go.etcd.io/etcd/client/v3 v3.5.16 h1:sSmVYOAHeC9doqi0gv7v86oY/BTld0SEFGaxsU9eRhE=
+go.etcd.io/etcd/client/v3 v3.5.16/go.mod h1:X+rExSGkyqxvu276cr2OwPLBaeqFu1cIl4vmRjAD/50=
+go.etcd.io/etcd/pkg/v3 v3.5.16 h1:cnavs5WSPWeK4TYwPYfmcr3Joz9BH+TZ6qoUtz6/+mc=
+go.etcd.io/etcd/pkg/v3 v3.5.16/go.mod h1:+lutCZHG5MBBFI/U4eYT5yL7sJfnexsoM20Y0t2uNuY=
+go.etcd.io/etcd/raft/v3 v3.5.16 h1:zBXA3ZUpYs1AwiLGPafYAKKl/CORn/uaxYDwlNwndAk=
+go.etcd.io/etcd/raft/v3 v3.5.16/go.mod h1:P4UP14AxofMJ/54boWilabqqWoW9eLodl6I5GdGzazI=
+go.etcd.io/etcd/server/v3 v3.5.16 h1:d0/SAdJ3vVsZvF8IFVb1k8zqMZ+heGcNfft71ul9GWE=
+go.etcd.io/etcd/server/v3 v3.5.16/go.mod h1:ynhyZZpdDp1Gq49jkUg5mfkDWZwXnn3eIqCqtJnrD/s=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
-go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
-go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
-go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/exporters/autoexport v0.46.1 h1:ysCfPZB9AjUlMa1UHYup3c9dAOCMQX/6sxSfPBUoxHw=
go.opentelemetry.io/contrib/exporters/autoexport v0.46.1/go.mod h1:ha0aiYm+DOPsLHjh0zoQ8W8sLT+LJ58J3j47lGpSLrU=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
-go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
-go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2guen0GhqH8o/G2un8f/aG/y++OuW6MyCo6hT9prXk=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0 h1:aLmmtjRke7LPDQ3lvpFz+kNEH43faFhzW7v8BFIEydg=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0/go.mod h1:TC1pyCt6G9Sjb4bQpShH+P5R53pO6ZuGnHuuln9xMeE=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
+go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw=
+go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.33.0 h1:7F29RDmnlqk6B5d+sUqemt8TBfDqxryYW5gX6L74RFA=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.33.0/go.mod h1:ZiGDq7xwDMKmWDrN1XsXAj0iC7hns+2DhxBFSncNHSE=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.33.0 h1:bSjzTvsXZbLSWU8hnZXcKmEVaJjjnandxD0PxThhVU8=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.33.0/go.mod h1:aj2rilHL8WjXY1I5V+ra+z8FELtk681deydgYT8ikxU=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I=
-go.opentelemetry.io/otel/exporters/prometheus v0.50.0 h1:2Ewsda6hejmbhGFyUvWZjUThC98Cf8Zy6g0zkIimOng=
-go.opentelemetry.io/otel/exporters/prometheus v0.50.0/go.mod h1:pMm5PkUo5YwbLiuEf7t2xg4wbP0/eSJrMxIMxKosynY=
-go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE=
-go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0/go.mod h1:DIzlHs3DRscCIBU3Y9YSzPfScwnYnzfnCd4g8zA7bZc=
+go.opentelemetry.io/otel/exporters/prometheus v0.55.0 h1:sSPw658Lk2NWAv74lkD3B/RSDb+xRFx46GjkrL3VUZo=
+go.opentelemetry.io/otel/exporters/prometheus v0.55.0/go.mod h1:nC00vyCmQixoeaxF6KNyP42II/RHa9UdruK02qBmHvI=
+go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.33.0 h1:FiOTYABOX4tdzi8A0+mtzcsTmi6WBOxk66u0f1Mj9Gs=
+go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.33.0/go.mod h1:xyo5rS8DgzV0Jtsht+LCEMwyiDbjpsxBpWETwFRF0/4=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E=
-go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
-go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
-go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
-go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
-go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08=
-go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg=
-go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
-go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
-go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
-go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
-go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
-go.starlark.net v0.0.0-20240520160348-046347dcd104 h1:3qhteRISupnJvaWshOmeqEUs2y9oc/+/ePPvDh3Eygg=
-go.starlark.net v0.0.0-20240520160348-046347dcd104/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8=
+go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ=
+go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M=
+go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM=
+go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM=
+go.opentelemetry.io/otel/sdk/metric v1.33.0 h1:Gs5VK9/WUJhNXZgn8MR6ITatvAmKeIuCtNbsP3JkNqU=
+go.opentelemetry.io/otel/sdk/metric v1.33.0/go.mod h1:dL5ykHZmm1B1nVRk9dDjChwDmt81MjVp3gLkQRwKf/Q=
+go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
+go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
+go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
+go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -1193,59 +935,26 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
-golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
-golang.org/x/crypto/x509roots/fallback v0.0.0-20240626151235-a6a393ffd658 h1:i7K6wQLN/0oxF7FT3tKkfMCstxoT4VGG36YIB9ZKLzI=
-golang.org/x/crypto/x509roots/fallback v0.0.0-20240626151235-a6a393ffd658/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8=
+golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
+golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
+golang.org/x/crypto/x509roots/fallback v0.0.0-20240904212608-c9da6b9a4008 h1:vKHSxFhPLnBEYu9R8DcQ4gXq9EqU0VVhC9pq9wmtYsg=
+golang.org/x/crypto/x509roots/fallback v0.0.0-20240904212608-c9da6b9a4008/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
-golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
-golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
-golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
-golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
-golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
-golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
-golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
+golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
-golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
-golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
-golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
+golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1258,100 +967,33 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/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-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
-golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
-golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
-golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
-golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
+golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
+golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
-golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
-golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
-golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
-golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
-golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A=
-golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
-golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
+golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
+golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1362,116 +1004,48 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
-golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
-golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
+golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
+golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
+golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
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=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
-golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
+golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -1480,278 +1054,48 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
-golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
-golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
-golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
-golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
+golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
+golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
-golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
-golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
-golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
-golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
-google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
-google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
-google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
-google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
-google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
-google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
-google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
-google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
-google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
-google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
-google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
-google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
-google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
-google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
-google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
-google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
-google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
-google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
-google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
-google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
-google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
-google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
-google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
-google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
-google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
-google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
-google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g=
-google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
-google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
-google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=
-google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
-google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
-google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
-google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=
-google.golang.org/api v0.172.0 h1:/1OcMZGPmW1rX2LCu2CmGUD1KXK1+pfzxotxyRUCCdk=
-google.golang.org/api v0.172.0/go.mod h1:+fJZq6QXWfa9pXhnIzsjx4yI22d4aI9ZpLb58gvXjis=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
-google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
-google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
-google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
-google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
-google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
-google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
-google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
-google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
-google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
-google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
-google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
-google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
-google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
-google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
-google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
-google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
-google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
-google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
-google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
-google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
-google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
-google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
-google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
-google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
-google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE=
-google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc=
-google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
-google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
-google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
-google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
-google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
-google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
-google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
-google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
-google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
-google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
-google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw=
-google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI=
-google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI=
-google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U=
-google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
-google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
-google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
-google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
-google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
+google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
+google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
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.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
-google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
-google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
-google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
-google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
-google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
-google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.44.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.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
-google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
-google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
-google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
-google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
-google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
+google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
+google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
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=
@@ -1760,15 +1104,9 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
+google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
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-20160105164936-4f90aeace3a2/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -1777,8 +1115,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
-gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
@@ -1787,6 +1123,8 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
@@ -1794,7 +1132,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -1809,43 +1146,39 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
-helm.sh/helm/v3 v3.15.3 h1:HcZDaVFe9uHa6hpsR54mJjYyRy4uz/pc6csg27nxFOc=
-helm.sh/helm/v3 v3.15.3/go.mod h1:FzSIP8jDQaa6WAVg9F+OkKz7J0ZmAga4MABtTbsb9WQ=
+helm.sh/helm/v3 v3.16.4 h1:rBn/h9MACw+QlhxQTjpl8Ifx+VTWaYsw3rguGBYBzr0=
+helm.sh/helm/v3 v3.16.4/go.mod h1:k8QPotUt57wWbi90w3LNmg3/MWcLPigVv+0/X4B8BzA=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
-honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
k8s.io/api v0.18.4/go.mod h1:lOIQAKYgai1+vz9J7YcDZwC26Z0zQewYOGWdyIPUUQ4=
-k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ=
-k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04=
+k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE=
+k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0=
k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY=
k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio=
-k8s.io/apiextensions-apiserver v0.30.3 h1:oChu5li2vsZHx2IvnGP3ah8Nj3KyqG3kRSaKmijhB9U=
-k8s.io/apiextensions-apiserver v0.30.3/go.mod h1:uhXxYDkMAvl6CJw4lrDN4CPbONkF3+XL9cacCT44kV4=
+k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0=
+k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw=
k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
-k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc=
-k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
+k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg=
+k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw=
k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8=
-k8s.io/apiserver v0.30.3 h1:QZJndA9k2MjFqpnyYv/PH+9PE0SHhx3hBho4X0vE65g=
-k8s.io/apiserver v0.30.3/go.mod h1:6Oa88y1CZqnzetd2JdepO0UXzQX4ZnOekx2/PtEjrOg=
-k8s.io/cli-runtime v0.30.3 h1:aG69oRzJuP2Q4o8dm+f5WJIX4ZBEwrvdID0+MXyUY6k=
-k8s.io/cli-runtime v0.30.3/go.mod h1:hwrrRdd9P84CXSKzhHxrOivAR9BRnkMt0OeP5mj7X30=
+k8s.io/apiserver v0.32.0 h1:VJ89ZvQZ8p1sLeiWdRJpRD6oLozNZD2+qVSLi+ft5Qs=
+k8s.io/apiserver v0.32.0/go.mod h1:HFh+dM1/BE/Hm4bS4nTXHVfN6Z6tFIZPi649n83b4Ag=
+k8s.io/cli-runtime v0.32.0 h1:dP+OZqs7zHPpGQMCGAhectbHU2SNCuZtIimRKTv2T1c=
+k8s.io/cli-runtime v0.32.0/go.mod h1:Mai8ht2+esoDRK5hr861KRy6z0zHsSTYttNVJXgP3YQ=
k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g=
-k8s.io/client-go v0.30.3 h1:bHrJu3xQZNXIi8/MoxYtZBBWQQXwy16zqJwloXXfD3k=
-k8s.io/client-go v0.30.3/go.mod h1:8d4pf8vYu665/kUbsxWAQ/JDBNWqfFeZnvFiVdmx89U=
+k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8=
+k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8=
k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM=
k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk=
-k8s.io/component-base v0.30.3 h1:Ci0UqKWf4oiwy8hr1+E3dsnliKnkMLZMVbWzeorlk7s=
-k8s.io/component-base v0.30.3/go.mod h1:C1SshT3rGPCuNtBs14RmVD2xW0EhRSeLvBh7AGk1quA=
+k8s.io/component-base v0.32.0 h1:d6cWHZkCiiep41ObYQS6IcgzOUQUNpywm39KVYaUqzU=
+k8s.io/component-base v0.32.0/go.mod h1:JLG2W5TUxUu5uDyKiH2R/7NnxJo1HlPoRIIbVLkK5eM=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
@@ -1854,47 +1187,48 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
+k8s.io/kms v0.32.0 h1:jwOfunHIrcdYl5FRcA+uUKKtg6qiqoPCwmS2T3XTYL4=
+k8s.io/kms v0.32.0/go.mod h1:Bk2evz/Yvk0oVrvm4MvZbgq8BD34Ksxs2SRHn4/UiOM=
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
-k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a h1:zD1uj3Jf+mD4zmA7W+goE5TxDkI7OGJjBNBzq5fJtLA=
-k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc=
-k8s.io/kubectl v0.30.3 h1:YIBBvMdTW0xcDpmrOBzcpUVsn+zOgjMYIu7kAq+yqiI=
-k8s.io/kubectl v0.30.3/go.mod h1:IcR0I9RN2+zzTRUa1BzZCm4oM0NLOawE6RzlDvd1Fpo=
-k8s.io/kubelet v0.30.2 h1:Ck4E/pHndI20IzDXxS57dElhDGASPO5pzXF7BcKfmCY=
-k8s.io/kubelet v0.30.2/go.mod h1:DSwwTbLQmdNkebAU7ypIALR4P9aXZNFwgRmedojUE94=
-k8s.io/metrics v0.30.3 h1:gKCpte5zykrOmQhZ8qmsxyJslMdiLN+sqbBfIWNpbGM=
-k8s.io/metrics v0.30.3/go.mod h1:W06L2nXRhOwPkFYDJYWdEIS3u6JcJy3ebIPYbndRs6A=
+k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg=
+k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas=
+k8s.io/kubectl v0.32.0 h1:rpxl+ng9qeG79YA4Em9tLSfX0G8W0vfaiPVrc/WR7Xw=
+k8s.io/kubectl v0.32.0/go.mod h1:qIjSX+QgPQUgdy8ps6eKsYNF+YmFOAO3WygfucIqFiE=
+k8s.io/metrics v0.32.0 h1:70qJ3ZS/9DrtH0UA0NVBI6gW2ip2GAn9e7NtoKERpns=
+k8s.io/metrics v0.32.0/go.mod h1:skdg9pDjVjCPIQqmc5rBzDL4noY64ORhKu9KCPv1+QI=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak=
-k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo=
-oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo=
+k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
+k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+oras.land/oras-go v1.2.6 h1:z8cmxQXBU8yZ4mkytWqXfo6tZcamPwjsuxYU81xJ8Lk=
+oras.land/oras-go v1.2.6/go.mod h1:OVPc1PegSEe/K8YiLfosrlqlqTN9PUyFvOw5Y9gwrT8=
periph.io/x/host/v3 v3.8.2 h1:ayKUDzgUCN0g8+/xM9GTkWaOBhSLVcVHGTfjAOi8OsQ=
periph.io/x/host/v3 v3.8.2/go.mod h1:yFL76AesNHR68PboofSWYaQTKmvPXsQH2Apvp/ls/K4=
-rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
-rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
-rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.1 h1:uOuSLOMBWkJH0TWa9X6l+mj5nZdm6Ay6Bli8HL8rNfk=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.1/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A=
-sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw=
-sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
+sigs.k8s.io/controller-runtime v0.19.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw=
+sigs.k8s.io/controller-runtime v0.19.3/go.mod h1:j4j87DqtsThvwTv5/Tc5NFRyyF/RF0ip4+62tbTSIUM=
sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI=
-sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM=
-sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
+sigs.k8s.io/gateway-api v1.2.1 h1:fZZ/+RyRb+Y5tGkwxFKuYuSRQHu9dZtbjenblleOLHM=
+sigs.k8s.io/gateway-api v1.2.1/go.mod h1:EpNfEXNjiYfUJypf0eZ0P5iXA9ekSGWaS1WgPaM42X0=
+sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
+sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/kind v0.8.1/go.mod h1:oNKTxUVPYkV9lWzY6CVMNluVq8cBsyq+UgPJdvA3uu4=
-sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g=
-sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0=
-sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ=
-sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U=
+sigs.k8s.io/kubectl-validate v0.0.5-0.20241223122011-eb064d2f92d5 h1:hNBVJn2bLSAw6vfO2HATzBZlSPMuz5zm+uE+0N1hQx4=
+sigs.k8s.io/kubectl-validate v0.0.5-0.20241223122011-eb064d2f92d5/go.mod h1:ch1ZkZlHzATEduEoItW1Dro09kDMuUsbqFDCyfO0P6I=
+sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo=
+sigs.k8s.io/kustomize/api v0.18.0/go.mod h1:f8isXnX+8b+SGLHQ6yO4JG1rdkZlvhaCf/uZbLVMb0U=
+sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt4E=
+sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo=
sigs.k8s.io/mcs-api v0.1.0 h1:edDbg0oRGfXw8TmZjKYep06LcJLv/qcYLidejnUp0PM=
sigs.k8s.io/mcs-api v0.1.0/go.mod h1:gGiAryeFNB4GBsq2LBmVqSgKoobLxt+p7ii/WG5QYYw=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
-sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
-sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
+sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk=
+sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
diff --git a/internal/admin/server.go b/internal/admin/server.go
index 0569513033e..f71619a2238 100644
--- a/internal/admin/server.go
+++ b/internal/admin/server.go
@@ -12,13 +12,9 @@ import (
"github.com/davecgh/go-spew/spew"
- egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
- "github.com/envoyproxy/gateway/internal/logging"
)
-var adminLogger = logging.DefaultLogger(egv1a1.LogLevelInfo).WithName("admin")
-
func Init(cfg *config.Server) error {
if cfg.EnvoyGateway.GetEnvoyGatewayAdmin().EnableDumpConfig {
spewConfig := spew.NewDefaultConfig()
@@ -34,6 +30,7 @@ func start(cfg *config.Server) error {
address := cfg.EnvoyGateway.GetEnvoyGatewayAdminAddress()
enablePprof := cfg.EnvoyGateway.GetEnvoyGatewayAdmin().EnablePprof
+ adminLogger := cfg.Logger.WithName("admin")
adminLogger.Info("starting admin server", "address", address, "enablePprof", enablePprof)
if enablePprof {
@@ -57,7 +54,7 @@ func start(cfg *config.Server) error {
// Listen And Serve Admin Server.
go func() {
if err := adminServer.ListenAndServe(); err != nil {
- cfg.Logger.Error(err, "start admin server failed")
+ adminLogger.Error(err, "start admin server failed")
}
}()
diff --git a/internal/admin/server_test.go b/internal/admin/server_test.go
index 2280738c235..a07291d8ba1 100644
--- a/internal/admin/server_test.go
+++ b/internal/admin/server_test.go
@@ -12,6 +12,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/logging"
)
func TestInitAdminServer(t *testing.T) {
@@ -20,6 +21,8 @@ func TestInitAdminServer(t *testing.T) {
EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{},
},
}
+
+ svrConfig.Logger = logging.NewLogger(egv1a1.DefaultEnvoyGatewayLogging())
err := Init(svrConfig)
require.NoError(t, err)
}
diff --git a/internal/cmd/certgen.go b/internal/cmd/certgen.go
index afa626f8d9a..cc9017a17bf 100644
--- a/internal/cmd/certgen.go
+++ b/internal/cmd/certgen.go
@@ -9,6 +9,7 @@ import (
"context"
"errors"
"fmt"
+ "path"
"github.com/spf13/cobra"
ctrl "sigs.k8s.io/controller-runtime"
@@ -19,23 +20,32 @@ import (
"github.com/envoyproxy/gateway/internal/envoygateway"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/provider/kubernetes"
+ "github.com/envoyproxy/gateway/internal/utils/file"
)
+// TODO: make this path configurable or use server config directly.
+const defaultLocalCertPath = "/tmp/envoy-gateway/certs"
+
// getCertGenCommand returns the certGen cobra command to be executed.
func getCertGenCommand() *cobra.Command {
+ var local bool
+
cmd := &cobra.Command{
Use: "certgen",
Short: "Generate Control Plane Certificates",
RunE: func(cmd *cobra.Command, args []string) error {
- return certGen()
+ return certGen(local)
},
}
+ cmd.PersistentFlags().BoolVarP(&local, "local", "l", false,
+ "Generate all the certificates locally.")
+
return cmd
}
// certGen generates control plane certificates.
-func certGen() error {
+func certGen(local bool) error {
cfg, err := getConfig()
if err != nil {
return err
@@ -46,22 +56,29 @@ func certGen() error {
if err != nil {
return fmt.Errorf("failed to generate certificates: %w", err)
}
- log.Info("generated certificates")
- cli, err := client.New(clicfg.GetConfigOrDie(), client.Options{Scheme: envoygateway.GetScheme()})
- if err != nil {
- return fmt.Errorf("failed to create controller-runtime client: %w", err)
- }
+ if !local {
+ log.Info("generated certificates")
+ cli, err := client.New(clicfg.GetConfigOrDie(), client.Options{Scheme: envoygateway.GetScheme()})
+ if err != nil {
+ return fmt.Errorf("failed to create controller-runtime client: %w", err)
+ }
- if err := outputCerts(ctrl.SetupSignalHandler(), cli, cfg, certs); err != nil {
- return fmt.Errorf("failed to output certificates: %w", err)
+ if err = outputCertsForKubernetes(ctrl.SetupSignalHandler(), cli, cfg, certs); err != nil {
+ return fmt.Errorf("failed to output certificates: %w", err)
+ }
+ } else {
+ log.Info("generated certificates", "path", defaultLocalCertPath)
+ if err = outputCertsForLocal(defaultLocalCertPath, certs); err != nil {
+ return fmt.Errorf("failed to output certificates locally: %w", err)
+ }
}
return nil
}
-// outputCerts outputs the provided certs to a secret in namespace ns.
-func outputCerts(ctx context.Context, cli client.Client, cfg *config.Server, certs *crypto.Certificates) error {
+// outputCertsForKubernetes outputs the provided certs to a secret in namespace ns.
+func outputCertsForKubernetes(ctx context.Context, cli client.Client, cfg *config.Server, certs *crypto.Certificates) error {
var updateSecrets bool
if cfg.EnvoyGateway != nil &&
cfg.EnvoyGateway.Provider != nil &&
@@ -88,3 +105,45 @@ func outputCerts(ctx context.Context, cli client.Client, cfg *config.Server, cer
return nil
}
+
+// outputCertsForLocal outputs the provided certs to the local directory as files.
+func outputCertsForLocal(localPath string, certs *crypto.Certificates) (err error) {
+ egDir := path.Join(localPath, "envoy-gateway")
+ if err = file.WriteDir(certs.CACertificate, egDir, "ca.crt"); err != nil {
+ return err
+ }
+ if err = file.WriteDir(certs.EnvoyGatewayCertificate, egDir, "tls.crt"); err != nil {
+ return err
+ }
+ if err = file.WriteDir(certs.EnvoyGatewayPrivateKey, egDir, "tls.key"); err != nil {
+ return err
+ }
+
+ envoyDir := path.Join(localPath, "envoy")
+ if err = file.WriteDir(certs.CACertificate, envoyDir, "ca.crt"); err != nil {
+ return err
+ }
+ if err = file.WriteDir(certs.EnvoyCertificate, envoyDir, "tls.crt"); err != nil {
+ return err
+ }
+ if err = file.WriteDir(certs.EnvoyPrivateKey, envoyDir, "tls.key"); err != nil {
+ return err
+ }
+
+ rlDir := path.Join(localPath, "envoy-rate-limit")
+ if err = file.WriteDir(certs.CACertificate, rlDir, "ca.crt"); err != nil {
+ return err
+ }
+ if err = file.WriteDir(certs.EnvoyRateLimitCertificate, rlDir, "tls.crt"); err != nil {
+ return err
+ }
+ if err = file.WriteDir(certs.EnvoyRateLimitPrivateKey, rlDir, "tls.key"); err != nil {
+ return err
+ }
+
+ if err = file.WriteDir(certs.OIDCHMACSecret, path.Join(localPath, "envoy-oidc-hmac"), "hmac-secret"); err != nil {
+ return err
+ }
+
+ return
+}
diff --git a/internal/cmd/certgen_test.go b/internal/cmd/certgen_test.go
index fedd07d2236..299b0e8df23 100644
--- a/internal/cmd/certgen_test.go
+++ b/internal/cmd/certgen_test.go
@@ -6,12 +6,39 @@
package cmd
import (
+ "path/filepath"
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/envoyproxy/gateway/internal/crypto"
)
func TestGetCertgenCommand(t *testing.T) {
got := getCertGenCommand()
assert.Equal(t, "certgen", got.Use)
}
+
+func TestOutputCertsForLocal(t *testing.T) {
+ cfg, err := getConfig()
+ require.NoError(t, err)
+
+ certs, err := crypto.GenerateCerts(cfg)
+ require.NoError(t, err)
+
+ tmpDir := t.TempDir()
+ err = outputCertsForLocal(tmpDir, certs)
+ require.NoError(t, err)
+
+ assert.FileExists(t, filepath.Join(tmpDir, "envoy-gateway", "ca.crt"))
+ assert.FileExists(t, filepath.Join(tmpDir, "envoy-gateway", "tls.crt"))
+ assert.FileExists(t, filepath.Join(tmpDir, "envoy-gateway", "tls.key"))
+ assert.FileExists(t, filepath.Join(tmpDir, "envoy", "ca.crt"))
+ assert.FileExists(t, filepath.Join(tmpDir, "envoy", "tls.crt"))
+ assert.FileExists(t, filepath.Join(tmpDir, "envoy", "tls.key"))
+ assert.FileExists(t, filepath.Join(tmpDir, "envoy-rate-limit", "ca.crt"))
+ assert.FileExists(t, filepath.Join(tmpDir, "envoy-rate-limit", "tls.crt"))
+ assert.FileExists(t, filepath.Join(tmpDir, "envoy-rate-limit", "tls.key"))
+ assert.FileExists(t, filepath.Join(tmpDir, "envoy-oidc-hmac", "hmac-secret"))
+}
diff --git a/internal/cmd/egctl/collect.go b/internal/cmd/egctl/collect.go
index e4eece22e53..e95db983eb3 100644
--- a/internal/cmd/egctl/collect.go
+++ b/internal/cmd/egctl/collect.go
@@ -15,12 +15,12 @@ import (
"syscall"
"time"
- "github.com/replicatedhq/troubleshoot/pkg/convert"
"github.com/spf13/cobra"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"github.com/envoyproxy/gateway/internal/cmd/options"
tb "github.com/envoyproxy/gateway/internal/troubleshoot"
+ "github.com/envoyproxy/gateway/internal/utils/path"
)
type collectOptions struct {
@@ -74,7 +74,7 @@ func runCollect(collectOpts collectOptions) error {
basename := ""
if collectOpts.outPath != "" {
// use override output path
- overridePath, err := convert.ValidateOutputPath(collectOpts.outPath)
+ overridePath, err := path.ValidateOutputPath(collectOpts.outPath)
if err != nil {
return fmt.Errorf("override output file path: %w", err)
}
diff --git a/internal/cmd/egctl/config.go b/internal/cmd/egctl/config.go
index 13a0f6bed21..501146676e0 100644
--- a/internal/cmd/egctl/config.go
+++ b/internal/cmd/egctl/config.go
@@ -79,7 +79,6 @@ func retrieveConfigDump(args []string, includeEds bool, configType envoyConfigTy
var wg sync.WaitGroup
wg.Add(len(pods))
for _, pod := range pods {
- pod := pod
go func() {
fw, err := portForwarder(cli, pod, adminPort)
if err != nil {
@@ -170,7 +169,6 @@ func fetchRunningEnvoyPods(c kube.CLIClient, nn types.NamespacedName, labelSelec
podsNamespacedNames := []types.NamespacedName{}
for _, pod := range pods {
- pod := pod
podNsName := utils.NamespacedName(&pod)
if pod.Status.Phase != "Running" {
return podsNamespacedNames, fmt.Errorf("pod %s is not running", podNsName)
diff --git a/internal/cmd/egctl/experimental.go b/internal/cmd/egctl/experimental.go
index 70f46650ff3..9af7e76f04a 100644
--- a/internal/cmd/egctl/experimental.go
+++ b/internal/cmd/egctl/experimental.go
@@ -29,6 +29,7 @@ func newExperimentalCommand() *cobra.Command {
experimentalCommand.AddCommand(newInstallCommand())
experimentalCommand.AddCommand(newUnInstallCommand())
experimentalCommand.AddCommand(newCollectCommand())
+ experimentalCommand.AddCommand(newValidateCommand())
return experimentalCommand
}
diff --git a/internal/cmd/egctl/status.go b/internal/cmd/egctl/status.go
index a19fdd978d4..814bd159339 100644
--- a/internal/cmd/egctl/status.go
+++ b/internal/cmd/egctl/status.go
@@ -23,22 +23,22 @@ import (
gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
- "github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
)
var (
supportedXRouteTypes = []string{
- gatewayapi.KindHTTPRoute, gatewayapi.KindGRPCRoute, gatewayapi.KindTCPRoute,
- gatewayapi.KindUDPRoute, gatewayapi.KindTLSRoute,
+ resource.KindHTTPRoute, resource.KindGRPCRoute, resource.KindTCPRoute,
+ resource.KindUDPRoute, resource.KindTLSRoute,
}
supportedXPolicyTypes = []string{
- gatewayapi.KindBackendTLSPolicy, gatewayapi.KindBackendTrafficPolicy, gatewayapi.KindClientTrafficPolicy,
- gatewayapi.KindSecurityPolicy, gatewayapi.KindEnvoyPatchPolicy, gatewayapi.KindEnvoyExtensionPolicy,
+ resource.KindBackendTLSPolicy, resource.KindBackendTrafficPolicy, resource.KindClientTrafficPolicy,
+ resource.KindSecurityPolicy, resource.KindEnvoyPatchPolicy, resource.KindEnvoyExtensionPolicy,
}
supportedAllTypes = []string{
- gatewayapi.KindGatewayClass, gatewayapi.KindGateway,
+ resource.KindGatewayClass, resource.KindGateway,
}
)
@@ -156,7 +156,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &gc
- resourceKind = gatewayapi.KindGatewayClass
+ resourceKind = resource.KindGatewayClass
case "gtw", "gateway":
gtw := gwapiv1.GatewayList{}
@@ -164,7 +164,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = >w
- resourceKind = gatewayapi.KindGateway
+ resourceKind = resource.KindGateway
case "httproute":
httproute := gwapiv1.HTTPRouteList{}
@@ -172,7 +172,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &httproute
- resourceKind = gatewayapi.KindHTTPRoute
+ resourceKind = resource.KindHTTPRoute
case "grpcroute":
grpcroute := gwapiv1.GRPCRouteList{}
@@ -180,7 +180,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &grpcroute
- resourceKind = gatewayapi.KindGRPCRoute
+ resourceKind = resource.KindGRPCRoute
case "tcproute":
tcproute := gwapiv1a2.TCPRouteList{}
@@ -188,7 +188,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &tcproute
- resourceKind = gatewayapi.KindTCPRoute
+ resourceKind = resource.KindTCPRoute
case "udproute":
udproute := gwapiv1a2.UDPRouteList{}
@@ -196,7 +196,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &udproute
- resourceKind = gatewayapi.KindUDPRoute
+ resourceKind = resource.KindUDPRoute
case "tlsroute":
tlsroute := gwapiv1a2.TLSRouteList{}
@@ -204,7 +204,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &tlsroute
- resourceKind = gatewayapi.KindTLSRoute
+ resourceKind = resource.KindTLSRoute
case "btlspolicy", "backendtlspolicy":
btlspolicy := gwapiv1a3.BackendTLSPolicyList{}
@@ -212,7 +212,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &btlspolicy
- resourceKind = gatewayapi.KindBackendTLSPolicy
+ resourceKind = resource.KindBackendTLSPolicy
case "btp", "backendtrafficpolicy":
btp := egv1a1.BackendTrafficPolicyList{}
@@ -220,7 +220,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &btp
- resourceKind = gatewayapi.KindBackendTrafficPolicy
+ resourceKind = resource.KindBackendTrafficPolicy
case "ctp", "clienttrafficpolicy":
ctp := egv1a1.ClientTrafficPolicyList{}
@@ -228,7 +228,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &ctp
- resourceKind = gatewayapi.KindClientTrafficPolicy
+ resourceKind = resource.KindClientTrafficPolicy
case "epp", "envoypatchpolicy":
epp := egv1a1.EnvoyPatchPolicyList{}
@@ -236,7 +236,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &epp
- resourceKind = gatewayapi.KindEnvoyPatchPolicy
+ resourceKind = resource.KindEnvoyPatchPolicy
case "eep", "envoyextensionpolicy":
eep := egv1a1.EnvoyExtensionPolicyList{}
@@ -244,7 +244,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &eep
- resourceKind = gatewayapi.KindEnvoyExtensionPolicy
+ resourceKind = resource.KindEnvoyExtensionPolicy
case "sp", "securitypolicy":
sp := egv1a1.SecurityPolicyList{}
@@ -252,7 +252,7 @@ func runStatus(ctx context.Context, cli client.Client, inputResourceType, namesp
return err
}
resourcesList = &sp
- resourceKind = gatewayapi.KindSecurityPolicy
+ resourceKind = resource.KindSecurityPolicy
default:
return fmt.Errorf("unknown input resource type: %s, supported input types are: %s",
diff --git a/internal/cmd/egctl/status_test.go b/internal/cmd/egctl/status_test.go
index 68123a6962b..2d2b6ad611c 100644
--- a/internal/cmd/egctl/status_test.go
+++ b/internal/cmd/egctl/status_test.go
@@ -19,6 +19,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
)
func TestWriteStatus(t *testing.T) {
@@ -40,7 +41,7 @@ func TestWriteStatus(t *testing.T) {
name: "egctl x status gc -v, but no resources",
resourceList: &gwapiv1.GatewayClassList{},
resourceNamespaced: false,
- resourceKind: gatewayapi.KindGatewayClass,
+ resourceKind: resource.KindGatewayClass,
quiet: false,
verbose: true,
allNamespaces: false,
@@ -80,7 +81,7 @@ func TestWriteStatus(t *testing.T) {
},
},
resourceNamespaced: false,
- resourceKind: gatewayapi.KindGatewayClass,
+ resourceKind: resource.KindGatewayClass,
quiet: false,
verbose: false,
allNamespaces: false,
@@ -122,7 +123,7 @@ gc foobar2 test-status-2 test reason 2
},
},
resourceNamespaced: false,
- resourceKind: gatewayapi.KindGatewayClass,
+ resourceKind: resource.KindGatewayClass,
quiet: false,
verbose: true,
allNamespaces: false,
@@ -164,7 +165,7 @@ gc foobar2 test-status-2 test reason 2 test message 2 123457
},
},
resourceNamespaced: false,
- resourceKind: gatewayapi.KindGatewayClass,
+ resourceKind: resource.KindGatewayClass,
quiet: true,
verbose: true,
allNamespaces: false,
@@ -177,7 +178,7 @@ gc foobar2 test-status-2 test reason 2 test message 2 123457
name: "egctl x status gtw -v -A, no resources",
resourceList: &gwapiv1.GatewayList{},
resourceNamespaced: true,
- resourceKind: gatewayapi.KindGateway,
+ resourceKind: resource.KindGateway,
quiet: false,
verbose: true,
allNamespaces: true,
@@ -218,7 +219,7 @@ gc foobar2 test-status-2 test reason 2 test message 2 123457
},
},
resourceNamespaced: true,
- resourceKind: gatewayapi.KindGateway,
+ resourceKind: resource.KindGateway,
quiet: false,
verbose: true,
allNamespaces: true,
@@ -287,7 +288,7 @@ default gtw foobar2 test-status-2 test reason 2 test message 2
},
},
resourceNamespaced: true,
- resourceKind: gatewayapi.KindGateway,
+ resourceKind: resource.KindGateway,
quiet: true,
verbose: true,
allNamespaces: true,
@@ -311,7 +312,7 @@ default2 gtw2 foobar4 test-status-4 test reason 4 test message 4
Parents: []gwapiv1.RouteParentStatus{
{
ParentRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test-1"),
},
Conditions: []metav1.Condition{
@@ -347,7 +348,7 @@ default2 gtw2 foobar4 test-status-4 test reason 4 test message 4
Parents: []gwapiv1.RouteParentStatus{
{
ParentRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test-2"),
},
Conditions: []metav1.Condition{
@@ -376,7 +377,7 @@ default2 gtw2 foobar4 test-status-4 test reason 4 test message 4
},
},
resourceNamespaced: true,
- resourceKind: gatewayapi.KindHTTPRoute,
+ resourceKind: resource.KindHTTPRoute,
quiet: false,
verbose: false,
allNamespaces: true,
@@ -402,7 +403,7 @@ default2 http2 gateway/test-2 foobar4 test-status-4 test reason 4
Parents: []gwapiv1.RouteParentStatus{
{
ParentRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test-1"),
},
Conditions: []metav1.Condition{
@@ -438,7 +439,7 @@ default2 http2 gateway/test-2 foobar4 test-status-4 test reason 4
Parents: []gwapiv1.RouteParentStatus{
{
ParentRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test-2"),
},
Conditions: []metav1.Condition{
@@ -467,7 +468,7 @@ default2 http2 gateway/test-2 foobar4 test-status-4 test reason 4
},
},
resourceNamespaced: true,
- resourceKind: gatewayapi.KindHTTPRoute,
+ resourceKind: resource.KindHTTPRoute,
quiet: true,
verbose: false,
allNamespaces: false,
@@ -491,7 +492,7 @@ http2 gateway/test-2 foobar4 test-status-4 test reason 4
Ancestors: []gwapiv1a2.PolicyAncestorStatus{
{
AncestorRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test"),
},
Conditions: []metav1.Condition{
@@ -519,7 +520,7 @@ http2 gateway/test-2 foobar4 test-status-4 test reason 4
},
},
resourceNamespaced: true,
- resourceKind: gatewayapi.KindBackendTLSPolicy,
+ resourceKind: resource.KindBackendTLSPolicy,
quiet: false,
verbose: false,
allNamespaces: false,
@@ -543,7 +544,7 @@ btls gateway/test foobar2 test-status-2 test reason 2
Parents: []gwapiv1.RouteParentStatus{
{
ParentRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test-1"),
},
Conditions: []metav1.Condition{
@@ -567,7 +568,7 @@ btls gateway/test foobar2 test-status-2 test reason 2
},
{
ParentRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test-2"),
},
Conditions: []metav1.Condition{
@@ -603,7 +604,7 @@ btls gateway/test foobar2 test-status-2 test reason 2
Parents: []gwapiv1.RouteParentStatus{
{
ParentRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test-3"),
},
Conditions: []metav1.Condition{
@@ -627,7 +628,7 @@ btls gateway/test foobar2 test-status-2 test reason 2
},
{
ParentRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test-4"),
},
Conditions: []metav1.Condition{
@@ -656,7 +657,7 @@ btls gateway/test foobar2 test-status-2 test reason 2
},
},
resourceNamespaced: true,
- resourceKind: gatewayapi.KindHTTPRoute,
+ resourceKind: resource.KindHTTPRoute,
quiet: false,
verbose: false,
allNamespaces: true,
@@ -685,7 +686,7 @@ default2 http2 gateway/test-3 foobar6 test-status-6 test reason 6
Ancestors: []gwapiv1a2.PolicyAncestorStatus{
{
AncestorRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test-1"),
},
Conditions: []metav1.Condition{
@@ -709,7 +710,7 @@ default2 http2 gateway/test-3 foobar6 test-status-6 test reason 6
},
{
AncestorRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindHTTPRoute),
+ Kind: gatewayapi.KindPtr(resource.KindHTTPRoute),
Name: gwapiv1.ObjectName("test-2"),
},
Conditions: []metav1.Condition{
@@ -743,7 +744,7 @@ default2 http2 gateway/test-3 foobar6 test-status-6 test reason 6
Ancestors: []gwapiv1a2.PolicyAncestorStatus{
{
AncestorRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGateway),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
Name: gwapiv1.ObjectName("test-3"),
},
Conditions: []metav1.Condition{
@@ -767,7 +768,7 @@ default2 http2 gateway/test-3 foobar6 test-status-6 test reason 6
},
{
AncestorRef: gwapiv1.ParentReference{
- Kind: gatewayapi.KindPtr(gatewayapi.KindGRPCRoute),
+ Kind: gatewayapi.KindPtr(resource.KindGRPCRoute),
Name: gwapiv1.ObjectName("test-4"),
},
Conditions: []metav1.Condition{
@@ -795,7 +796,7 @@ default2 http2 gateway/test-3 foobar6 test-status-6 test reason 6
},
},
resourceNamespaced: true,
- resourceKind: gatewayapi.KindBackendTrafficPolicy,
+ resourceKind: resource.KindBackendTrafficPolicy,
quiet: false,
verbose: false,
allNamespaces: false,
diff --git a/internal/cmd/egctl/testdata/translate/in/backend-endpoint.yaml b/internal/cmd/egctl/testdata/translate/in/backend-endpoint.yaml
new file mode 100644
index 00000000000..d2aa0f78f07
--- /dev/null
+++ b/internal/cmd/egctl/testdata/translate/in/backend-endpoint.yaml
@@ -0,0 +1,46 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+ name: eg
+spec:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+ name: eg
+spec:
+ gatewayClassName: eg
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: backend
+spec:
+ parentRefs:
+ - name: eg
+ hostnames:
+ - "www.example.com"
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend
+ matches:
+ - path:
+ type: PathPrefix
+ value: /
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend
+spec:
+ endpoints:
+ - ip:
+ address: 0.0.0.0
+ port: 3000
diff --git a/internal/cmd/egctl/testdata/translate/in/default-resources.yaml b/internal/cmd/egctl/testdata/translate/in/default-resources.yaml
index 1cdb52f993a..bf2af30da40 100644
--- a/internal/cmd/egctl/testdata/translate/in/default-resources.yaml
+++ b/internal/cmd/egctl/testdata/translate/in/default-resources.yaml
@@ -1,3 +1,4 @@
+---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
@@ -113,7 +114,7 @@ spec:
type: PathPrefix
value: /
---
-apiVersion: gateway.networking.k8s.io/v1alpha2
+apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: backend
diff --git a/internal/cmd/egctl/testdata/translate/in/from-gateway-api-to-xds.yaml b/internal/cmd/egctl/testdata/translate/in/from-gateway-api-to-xds.yaml
index b13096a2e3a..b501a74a758 100644
--- a/internal/cmd/egctl/testdata/translate/in/from-gateway-api-to-xds.yaml
+++ b/internal/cmd/egctl/testdata/translate/in/from-gateway-api-to-xds.yaml
@@ -145,7 +145,7 @@ spec:
type: PathPrefix
value: /
---
-apiVersion: gateway.networking.k8s.io/v1alpha2
+apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: backend
diff --git a/internal/cmd/egctl/testdata/translate/in/invalid-envoyproxy.yaml b/internal/cmd/egctl/testdata/translate/in/invalid-envoyproxy.yaml
index 9e31a94aa6a..5c72cb4f1bd 100644
--- a/internal/cmd/egctl/testdata/translate/in/invalid-envoyproxy.yaml
+++ b/internal/cmd/egctl/testdata/translate/in/invalid-envoyproxy.yaml
@@ -170,7 +170,7 @@ spec:
type: PathPrefix
value: /
---
-apiVersion: gateway.networking.k8s.io/v1alpha2
+apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: backend
diff --git a/internal/cmd/egctl/testdata/translate/in/valid-envoyproxy.yaml b/internal/cmd/egctl/testdata/translate/in/valid-envoyproxy.yaml
index bb9ca9478f9..ba8c25e2352 100644
--- a/internal/cmd/egctl/testdata/translate/in/valid-envoyproxy.yaml
+++ b/internal/cmd/egctl/testdata/translate/in/valid-envoyproxy.yaml
@@ -163,7 +163,7 @@ spec:
type: PathPrefix
value: /
---
-apiVersion: gateway.networking.k8s.io/v1alpha2
+apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: backend
diff --git a/internal/cmd/egctl/testdata/translate/out/backend-endpoint.all.yaml b/internal/cmd/egctl/testdata/translate/out/backend-endpoint.all.yaml
new file mode 100644
index 00000000000..d3f3ed2c771
--- /dev/null
+++ b/internal/cmd/egctl/testdata/translate/out/backend-endpoint.all.yaml
@@ -0,0 +1,106 @@
+backends:
+- kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend
+ namespace: envoy-gateway-system
+ spec:
+ endpoints:
+ - ip:
+ address: 0.0.0.0
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+gatewayClass:
+ kind: GatewayClass
+ metadata:
+ creationTimestamp: null
+ name: eg
+ namespace: envoy-gateway-system
+ spec:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: Valid GatewayClass
+ reason: Accepted
+ status: "True"
+ type: Accepted
+gateways:
+- kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: eg
+ namespace: envoy-gateway-system
+ spec:
+ gatewayClassName: eg
+ listeners:
+ - name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: backend
+ namespace: envoy-gateway-system
+ spec:
+ hostnames:
+ - www.example.com
+ parentRefs:
+ - name: eg
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend
+ matches:
+ - path:
+ type: PathPrefix
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: eg
diff --git a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml
index 86df2f9de4c..45694a36004 100644
--- a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml
@@ -43,7 +43,7 @@ envoyProxyForGatewayClass:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -122,13 +122,13 @@ envoyProxyForGatewayClass:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -160,13 +160,13 @@ envoyProxyForGatewayClass:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -178,6 +178,7 @@ envoyProxyForGatewayClass:
logging: {}
status: {}
gatewayClass:
+ kind: GatewayClass
metadata:
creationTimestamp: null
name: eg
@@ -197,7 +198,8 @@ gatewayClass:
status: "True"
type: Accepted
gateways:
-- metadata:
+- kind: Gateway
+ metadata:
creationTimestamp: null
name: eg
namespace: default
@@ -770,15 +772,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/backend/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/backend/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -789,22 +791,24 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: grpcroute/default/backend/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: grpcroute/default/backend/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
- cluster:
'@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
circuitBreakers:
@@ -813,15 +817,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcproute/default/backend/rule/-1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcproute/default/backend/rule/-1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -832,15 +836,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tlsroute/default/backend/rule/-1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tlsroute/default/backend/rule/-1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -851,15 +855,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: udproute/default/backend/rule/-1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: udproute/default/backend/rule/-1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- '@type': type.googleapis.com/envoy.admin.v3.ListenersConfigDump
@@ -918,10 +922,9 @@ xds:
resourceApiVersion: V3
routeConfigName: default/eg/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: default/eg/http
- drainType: MODIFY_ONLY
name: default/eg/http
perConnectionBufferLimitBytes: 32768
- activeState:
@@ -986,10 +989,9 @@ xds:
resourceApiVersion: V3
routeConfigName: default/eg/grpc
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8080
useRemoteAddress: true
name: default/eg/grpc
- drainType: MODIFY_ONLY
name: default/eg/grpc
perConnectionBufferLimitBytes: 32768
- activeState:
@@ -1012,7 +1014,6 @@ xds:
socketAddress:
address: 0.0.0.0
portValue: 1234
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
@@ -1028,7 +1029,7 @@ xds:
{"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
path: /dev/stdout
cluster: tcproute/default/backend/rule/-1
- statPrefix: tcp
+ statPrefix: tcp-1234
name: tcproute/default/backend
name: default/eg/tcp
perConnectionBufferLimitBytes: 32768
@@ -1052,7 +1053,6 @@ xds:
socketAddress:
address: 0.0.0.0
portValue: 8443
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -1071,7 +1071,7 @@ xds:
{"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
path: /dev/stdout
cluster: tlsroute/default/backend/rule/-1
- statPrefix: passthrough
+ statPrefix: tls-passthrough-8443
name: tlsroute/default/backend
listenerFilters:
- name: envoy.filters.listener.tls_inspector
@@ -1135,7 +1135,7 @@ xds:
filterMetadata:
envoy-gateway:
resources:
- - kind: ""
+ - kind: Gateway
name: eg
namespace: default
sectionName: http
@@ -1166,7 +1166,7 @@ xds:
filterMetadata:
envoy-gateway:
resources:
- - kind: ""
+ - kind: Gateway
name: eg
namespace: default
sectionName: grpc
diff --git a/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.cluster.yaml b/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.cluster.yaml
index 3d88f20f51d..de5d16949be 100644
--- a/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.cluster.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.cluster.yaml
@@ -1,4 +1,5 @@
gatewayClass:
+ kind: GatewayClass
metadata:
creationTimestamp: null
name: eg
@@ -13,7 +14,8 @@ gatewayClass:
status: "True"
type: Accepted
gateways:
-- metadata:
+- kind: Gateway
+ metadata:
creationTimestamp: null
name: eg
namespace: envoy-gateway-system
@@ -98,14 +100,14 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/envoy-gateway-system/backend/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/envoy-gateway-system/backend/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.route.json b/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.route.json
index 41dfd6683e7..f069c670afb 100644
--- a/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.route.json
+++ b/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.route.json
@@ -1,5 +1,6 @@
{
"gatewayClass": {
+ "kind": "GatewayClass",
"metadata": {
"name": "eg",
"namespace": "envoy-gateway-system",
@@ -22,6 +23,7 @@
},
"gateways": [
{
+ "kind": "Gateway",
"metadata": {
"name": "eg",
"namespace": "envoy-gateway-system",
diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json
index 14d29a32be2..4e914e3e78d 100644
--- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json
+++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json
@@ -458,7 +458,7 @@
"localityWeightedLbConfig": {}
},
"connectTimeout": "10s",
- "dnsLookupFamily": "V4_ONLY",
+ "dnsLookupFamily": "V4_PREFERRED",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
@@ -466,9 +466,9 @@
},
"serviceName": "httproute/default/backend/rule/0"
},
+ "ignoreHealthOnHostRemoval": true,
"lbPolicy": "LEAST_REQUEST",
"name": "httproute/default/backend/rule/0",
- "outlierDetection": {},
"perConnectionBufferLimitBytes": 32768,
"type": "EDS"
}
@@ -487,7 +487,7 @@
"localityWeightedLbConfig": {}
},
"connectTimeout": "10s",
- "dnsLookupFamily": "V4_ONLY",
+ "dnsLookupFamily": "V4_PREFERRED",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
@@ -495,16 +495,19 @@
},
"serviceName": "grpcroute/default/backend/rule/0"
},
+ "ignoreHealthOnHostRemoval": true,
"lbPolicy": "LEAST_REQUEST",
"name": "grpcroute/default/backend/rule/0",
- "outlierDetection": {},
"perConnectionBufferLimitBytes": 32768,
"type": "EDS",
"typedExtensionProtocolOptions": {
"envoy.extensions.upstreams.http.v3.HttpProtocolOptions": {
"@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions",
"explicitHttpConfig": {
- "http2ProtocolOptions": {}
+ "http2ProtocolOptions": {
+ "initialConnectionWindowSize": 1048576,
+ "initialStreamWindowSize": 65536
+ }
}
}
}
@@ -524,7 +527,7 @@
"localityWeightedLbConfig": {}
},
"connectTimeout": "10s",
- "dnsLookupFamily": "V4_ONLY",
+ "dnsLookupFamily": "V4_PREFERRED",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
@@ -532,9 +535,9 @@
},
"serviceName": "tcproute/default/backend/rule/-1"
},
+ "ignoreHealthOnHostRemoval": true,
"lbPolicy": "LEAST_REQUEST",
"name": "tcproute/default/backend/rule/-1",
- "outlierDetection": {},
"perConnectionBufferLimitBytes": 32768,
"type": "EDS"
}
@@ -553,7 +556,7 @@
"localityWeightedLbConfig": {}
},
"connectTimeout": "10s",
- "dnsLookupFamily": "V4_ONLY",
+ "dnsLookupFamily": "V4_PREFERRED",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
@@ -561,9 +564,9 @@
},
"serviceName": "tlsroute/default/backend/rule/-1"
},
+ "ignoreHealthOnHostRemoval": true,
"lbPolicy": "LEAST_REQUEST",
"name": "tlsroute/default/backend/rule/-1",
- "outlierDetection": {},
"perConnectionBufferLimitBytes": 32768,
"type": "EDS"
}
@@ -582,7 +585,7 @@
"localityWeightedLbConfig": {}
},
"connectTimeout": "10s",
- "dnsLookupFamily": "V4_ONLY",
+ "dnsLookupFamily": "V4_PREFERRED",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
@@ -590,9 +593,9 @@
},
"serviceName": "udproute/default/backend/rule/-1"
},
+ "ignoreHealthOnHostRemoval": true,
"lbPolicy": "LEAST_REQUEST",
"name": "udproute/default/backend/rule/-1",
- "outlierDetection": {},
"perConnectionBufferLimitBytes": 32768,
"type": "EDS"
}
@@ -681,14 +684,13 @@
"routeConfigName": "default/eg/http"
},
"serverHeaderTransformation": "PASS_THROUGH",
- "statPrefix": "http",
+ "statPrefix": "http-10080",
"useRemoteAddress": true
}
}
],
"name": "default/eg/http"
},
- "drainType": "MODIFY_ONLY",
"name": "default/eg/http",
"perConnectionBufferLimitBytes": 32768
}
@@ -787,14 +789,13 @@
"routeConfigName": "default/eg/grpc"
},
"serverHeaderTransformation": "PASS_THROUGH",
- "statPrefix": "http",
+ "statPrefix": "http-8080",
"useRemoteAddress": true
}
}
],
"name": "default/eg/grpc"
},
- "drainType": "MODIFY_ONLY",
"name": "default/eg/grpc",
"perConnectionBufferLimitBytes": 32768
}
@@ -831,7 +832,6 @@
"portValue": 1234
}
},
- "drainType": "MODIFY_ONLY",
"filterChains": [
{
"filters": [
@@ -854,7 +854,7 @@
}
],
"cluster": "tcproute/default/backend/rule/-1",
- "statPrefix": "tcp"
+ "statPrefix": "tcp-1234"
}
}
],
@@ -897,7 +897,6 @@
"portValue": 8443
}
},
- "drainType": "MODIFY_ONLY",
"filterChains": [
{
"filterChainMatch": {
@@ -925,7 +924,7 @@
}
],
"cluster": "tlsroute/default/backend/rule/-1",
- "statPrefix": "passthrough"
+ "statPrefix": "tls-passthrough-8443"
}
}
],
@@ -1035,7 +1034,7 @@
"envoy-gateway": {
"resources": [
{
- "kind": "",
+ "kind": "Gateway",
"name": "eg",
"namespace": "default",
"sectionName": "http"
@@ -1093,7 +1092,7 @@
"envoy-gateway": {
"resources": [
{
- "kind": "",
+ "kind": "Gateway",
"name": "eg",
"namespace": "default",
"sectionName": "grpc"
diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml
index a8fb322e28b..bcf16fe4f3a 100644
--- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml
@@ -251,15 +251,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/backend/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/backend/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -270,22 +270,24 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: grpcroute/default/backend/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: grpcroute/default/backend/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
- cluster:
'@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
circuitBreakers:
@@ -294,15 +296,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcproute/default/backend/rule/-1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcproute/default/backend/rule/-1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -313,15 +315,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tlsroute/default/backend/rule/-1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tlsroute/default/backend/rule/-1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -332,15 +334,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: udproute/default/backend/rule/-1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: udproute/default/backend/rule/-1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- '@type': type.googleapis.com/envoy.admin.v3.ListenersConfigDump
@@ -399,10 +401,9 @@ xds:
resourceApiVersion: V3
routeConfigName: default/eg/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: default/eg/http
- drainType: MODIFY_ONLY
name: default/eg/http
perConnectionBufferLimitBytes: 32768
- activeState:
@@ -467,10 +468,9 @@ xds:
resourceApiVersion: V3
routeConfigName: default/eg/grpc
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8080
useRemoteAddress: true
name: default/eg/grpc
- drainType: MODIFY_ONLY
name: default/eg/grpc
perConnectionBufferLimitBytes: 32768
- activeState:
@@ -493,7 +493,6 @@ xds:
socketAddress:
address: 0.0.0.0
portValue: 1234
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
@@ -509,7 +508,7 @@ xds:
{"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
path: /dev/stdout
cluster: tcproute/default/backend/rule/-1
- statPrefix: tcp
+ statPrefix: tcp-1234
name: tcproute/default/backend
name: default/eg/tcp
perConnectionBufferLimitBytes: 32768
@@ -533,7 +532,6 @@ xds:
socketAddress:
address: 0.0.0.0
portValue: 8443
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -552,7 +550,7 @@ xds:
{"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
path: /dev/stdout
cluster: tlsroute/default/backend/rule/-1
- statPrefix: passthrough
+ statPrefix: tls-passthrough-8443
name: tlsroute/default/backend
listenerFilters:
- name: envoy.filters.listener.tls_inspector
@@ -616,7 +614,7 @@ xds:
filterMetadata:
envoy-gateway:
resources:
- - kind: ""
+ - kind: Gateway
name: eg
namespace: default
sectionName: http
@@ -647,7 +645,7 @@ xds:
filterMetadata:
envoy-gateway:
resources:
- - kind: ""
+ - kind: Gateway
name: eg
namespace: default
sectionName: grpc
diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml
index 3d9bce8ad21..d171965d1c9 100644
--- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml
@@ -10,15 +10,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/backend/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/backend/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -29,22 +29,24 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: grpcroute/default/backend/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: grpcroute/default/backend/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
- cluster:
'@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
circuitBreakers:
@@ -53,15 +55,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcproute/default/backend/rule/-1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcproute/default/backend/rule/-1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -72,15 +74,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tlsroute/default/backend/rule/-1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tlsroute/default/backend/rule/-1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -91,14 +93,14 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: udproute/default/backend/rule/-1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: udproute/default/backend/rule/-1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml
index c151e22c7cc..b6c94a95ae8 100644
--- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml
@@ -56,10 +56,9 @@ xds:
resourceApiVersion: V3
routeConfigName: default/eg/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: default/eg/http
- drainType: MODIFY_ONLY
name: default/eg/http
perConnectionBufferLimitBytes: 32768
- activeState:
@@ -124,10 +123,9 @@ xds:
resourceApiVersion: V3
routeConfigName: default/eg/grpc
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8080
useRemoteAddress: true
name: default/eg/grpc
- drainType: MODIFY_ONLY
name: default/eg/grpc
perConnectionBufferLimitBytes: 32768
- activeState:
@@ -150,7 +148,6 @@ xds:
socketAddress:
address: 0.0.0.0
portValue: 1234
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
@@ -166,7 +163,7 @@ xds:
{"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
path: /dev/stdout
cluster: tcproute/default/backend/rule/-1
- statPrefix: tcp
+ statPrefix: tcp-1234
name: tcproute/default/backend
name: default/eg/tcp
perConnectionBufferLimitBytes: 32768
@@ -190,7 +187,6 @@ xds:
socketAddress:
address: 0.0.0.0
portValue: 8443
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -209,7 +205,7 @@ xds:
{"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
path: /dev/stdout
cluster: tlsroute/default/backend/rule/-1
- statPrefix: passthrough
+ statPrefix: tls-passthrough-8443
name: tlsroute/default/backend
listenerFilters:
- name: envoy.filters.listener.tls_inspector
diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.route.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.route.yaml
index 2163c6fb6bf..8ef62d3bf70 100644
--- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.route.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.route.yaml
@@ -13,7 +13,7 @@ xds:
filterMetadata:
envoy-gateway:
resources:
- - kind: ""
+ - kind: Gateway
name: eg
namespace: default
sectionName: http
@@ -44,7 +44,7 @@ xds:
filterMetadata:
envoy-gateway:
resources:
- - kind: ""
+ - kind: Gateway
name: eg
namespace: default
sectionName: grpc
diff --git a/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml b/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml
index 81df01be9e4..bd4ac1d198d 100644
--- a/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml
@@ -1,4 +1,5 @@
envoyProxyForGatewayClass:
+ kind: EnvoyProxy
metadata:
creationTimestamp: null
name: example
@@ -6,7 +7,7 @@ envoyProxyForGatewayClass:
spec:
bootstrap:
type: Replace
- value: |-
+ value: |
admin:
access_log:
- name: envoy.access_loggers.file
@@ -20,6 +21,7 @@ envoyProxyForGatewayClass:
logging: {}
status: {}
gatewayClass:
+ kind: GatewayClass
metadata:
creationTimestamp: null
name: eg
@@ -39,7 +41,8 @@ gatewayClass:
status: "False"
type: Accepted
gateways:
-- metadata:
+- kind: Gateway
+ metadata:
creationTimestamp: null
name: eg
namespace: default
diff --git a/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.all.json b/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.all.json
index 3d786413e60..730686a71d1 100644
--- a/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.all.json
+++ b/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.all.json
@@ -350,7 +350,7 @@
"localityWeightedLbConfig": {}
},
"connectTimeout": "10s",
- "dnsLookupFamily": "V4_ONLY",
+ "dnsLookupFamily": "V4_PREFERRED",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
@@ -358,9 +358,9 @@
},
"serviceName": "httproute/envoy-gateway-system/backend/rule/0"
},
+ "ignoreHealthOnHostRemoval": true,
"lbPolicy": "LEAST_REQUEST",
"name": "httproute/envoy-gateway-system/backend/rule/0",
- "outlierDetection": {},
"perConnectionBufferLimitBytes": 32768,
"type": "EDS"
}
@@ -379,7 +379,7 @@
"localityWeightedLbConfig": {}
},
"connectTimeout": "10s",
- "dnsLookupFamily": "V4_ONLY",
+ "dnsLookupFamily": "V4_PREFERRED",
"dnsRefreshRate": "30s",
"lbPolicy": "LEAST_REQUEST",
"loadAssignment": {
@@ -407,7 +407,6 @@
]
},
"name": "raw_githubusercontent_com_443",
- "outlierDetection": {},
"perConnectionBufferLimitBytes": 32768,
"respectDnsTtl": true,
"transportSocket": {
@@ -499,6 +498,12 @@
"providers": {
"httproute/envoy-gateway-system/backend/rule/0/match/0/www_example_com/example": {
"forward": true,
+ "normalizePayloadInMetadata": {
+ "spaceDelimitedClaims": [
+ "scope"
+ ]
+ },
+ "payloadInMetadata": "example",
"remoteJwks": {
"asyncFetch": {},
"cacheDuration": "300s",
@@ -506,8 +511,7 @@
"cluster": "raw_githubusercontent_com_443",
"timeout": "10s",
"uri": "https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/jwks.json"
- },
- "retryPolicy": {}
+ }
}
}
},
@@ -537,14 +541,13 @@
"routeConfigName": "envoy-gateway-system/eg/http"
},
"serverHeaderTransformation": "PASS_THROUGH",
- "statPrefix": "http",
+ "statPrefix": "http-10080",
"useRemoteAddress": true
}
}
],
"name": "envoy-gateway-system/eg/http"
},
- "drainType": "MODIFY_ONLY",
"name": "envoy-gateway-system/eg/http",
"perConnectionBufferLimitBytes": 32768
}
@@ -570,7 +573,7 @@
"envoy-gateway": {
"resources": [
{
- "kind": "",
+ "kind": "Gateway",
"name": "eg",
"namespace": "envoy-gateway-system",
"sectionName": "http"
diff --git a/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.all.yaml b/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.all.yaml
index 9f54fcc5d1b..9e6bbb5e316 100644
--- a/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.all.yaml
@@ -195,15 +195,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/envoy-gateway-system/backend/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/envoy-gateway-system/backend/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -214,7 +214,7 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -231,7 +231,6 @@ xds:
locality:
region: raw_githubusercontent_com_443/backend/0
name: raw_githubusercontent_com_443
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
@@ -293,6 +292,10 @@ xds:
providers:
httproute/envoy-gateway-system/backend/rule/0/match/0/www_example_com/example:
forward: true
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -300,7 +303,6 @@ xds:
cluster: raw_githubusercontent_com_443
timeout: 10s
uri: https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/jwks.json
- retryPolicy: {}
requirementMap:
httproute/envoy-gateway-system/backend/rule/0/match/0/www_example_com:
providerName: httproute/envoy-gateway-system/backend/rule/0/match/0/www_example_com/example
@@ -317,10 +319,9 @@ xds:
resourceApiVersion: V3
routeConfigName: envoy-gateway-system/eg/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway-system/eg/http
- drainType: MODIFY_ONLY
name: envoy-gateway-system/eg/http
perConnectionBufferLimitBytes: 32768
- '@type': type.googleapis.com/envoy.admin.v3.RoutesConfigDump
@@ -336,7 +337,7 @@ xds:
filterMetadata:
envoy-gateway:
resources:
- - kind: ""
+ - kind: Gateway
name: eg
namespace: envoy-gateway-system
sectionName: http
diff --git a/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.cluster.yaml b/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.cluster.yaml
index d0add370ce3..16c03a44810 100644
--- a/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.cluster.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.cluster.yaml
@@ -10,15 +10,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/envoy-gateway-system/backend/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/envoy-gateway-system/backend/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- cluster:
@@ -29,7 +29,7 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -46,7 +46,6 @@ xds:
locality:
region: raw_githubusercontent_com_443/backend/0
name: raw_githubusercontent_com_443
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
diff --git a/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.listener.yaml b/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.listener.yaml
index 3d2efd91270..c9ee8194bf9 100644
--- a/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.listener.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.listener.yaml
@@ -49,6 +49,10 @@ xds:
providers:
httproute/envoy-gateway-system/backend/rule/0/match/0/www_example_com/example:
forward: true
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -56,7 +60,6 @@ xds:
cluster: raw_githubusercontent_com_443
timeout: 10s
uri: https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/jwks.json
- retryPolicy: {}
requirementMap:
httproute/envoy-gateway-system/backend/rule/0/match/0/www_example_com:
providerName: httproute/envoy-gateway-system/backend/rule/0/match/0/www_example_com/example
@@ -73,9 +76,8 @@ xds:
resourceApiVersion: V3
routeConfigName: envoy-gateway-system/eg/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway-system/eg/http
- drainType: MODIFY_ONLY
name: envoy-gateway-system/eg/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.route.yaml b/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.route.yaml
index 7e8a1adeed0..bac80f6e5d3 100644
--- a/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.route.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/jwt-single-route-single-match-to-xds.route.yaml
@@ -13,7 +13,7 @@ xds:
filterMetadata:
envoy-gateway:
resources:
- - kind: ""
+ - kind: Gateway
name: eg
namespace: envoy-gateway-system
sectionName: http
diff --git a/internal/cmd/egctl/testdata/translate/out/multiple-xds.route.json b/internal/cmd/egctl/testdata/translate/out/multiple-xds.route.json
index 335fffb6d41..7748851144e 100644
--- a/internal/cmd/egctl/testdata/translate/out/multiple-xds.route.json
+++ b/internal/cmd/egctl/testdata/translate/out/multiple-xds.route.json
@@ -18,7 +18,7 @@
"envoy-gateway": {
"resources": [
{
- "kind": "",
+ "kind": "Gateway",
"name": "eg",
"namespace": "default",
"sectionName": "http"
@@ -81,7 +81,7 @@
"envoy-gateway": {
"resources": [
{
- "kind": "",
+ "kind": "Gateway",
"name": "eg2",
"namespace": "default",
"sectionName": "http"
diff --git a/internal/cmd/egctl/testdata/translate/out/no-service-cluster-ip.all.yaml b/internal/cmd/egctl/testdata/translate/out/no-service-cluster-ip.all.yaml
index 73ea76b01e6..b12a3c04939 100644
--- a/internal/cmd/egctl/testdata/translate/out/no-service-cluster-ip.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/no-service-cluster-ip.all.yaml
@@ -195,15 +195,15 @@ xds:
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/envoy-gateway-system/routes/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/envoy-gateway-system/routes/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- '@type': type.googleapis.com/envoy.admin.v3.ListenersConfigDump
@@ -262,10 +262,9 @@ xds:
resourceApiVersion: V3
routeConfigName: envoy-gateway-system/eg/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway-system/eg/http
- drainType: MODIFY_ONLY
name: envoy-gateway-system/eg/http
perConnectionBufferLimitBytes: 32768
- '@type': type.googleapis.com/envoy.admin.v3.RoutesConfigDump
@@ -281,7 +280,7 @@ xds:
filterMetadata:
envoy-gateway:
resources:
- - kind: ""
+ - kind: Gateway
name: eg
namespace: envoy-gateway-system
sectionName: http
diff --git a/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml b/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml
index 9f9515e8e58..de96e757e8e 100644
--- a/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml
@@ -1,5 +1,6 @@
gateways:
-- metadata:
+- kind: Gateway
+ metadata:
creationTimestamp: null
name: eg
namespace: envoy-gateway-system
@@ -99,6 +100,7 @@ xdsIR:
- '*'
isHTTP2: false
metadata:
+ kind: Gateway
name: eg
namespace: envoy-gateway-system
sectionName: http
diff --git a/internal/cmd/egctl/testdata/translate/out/quickstart.route.yaml b/internal/cmd/egctl/testdata/translate/out/quickstart.route.yaml
index a9149572285..7043ed9a5b7 100644
--- a/internal/cmd/egctl/testdata/translate/out/quickstart.route.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/quickstart.route.yaml
@@ -13,7 +13,7 @@ xds:
filterMetadata:
envoy-gateway:
resources:
- - kind: ""
+ - kind: Gateway
name: eg
namespace: envoy-gateway-system
sectionName: http
diff --git a/internal/cmd/egctl/testdata/translate/out/rejected-http-route.route.yaml b/internal/cmd/egctl/testdata/translate/out/rejected-http-route.route.yaml
index c578d14aef5..18e5910acc2 100644
--- a/internal/cmd/egctl/testdata/translate/out/rejected-http-route.route.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/rejected-http-route.route.yaml
@@ -1,4 +1,5 @@
gatewayClass:
+ kind: GatewayClass
metadata:
creationTimestamp: null
name: eg
@@ -13,7 +14,8 @@ gatewayClass:
status: "True"
type: Accepted
gateways:
-- metadata:
+- kind: Gateway
+ metadata:
creationTimestamp: null
name: eg
namespace: envoy-gateway-system
diff --git a/internal/cmd/egctl/testdata/translate/out/valid-envoyproxy.all.yaml b/internal/cmd/egctl/testdata/translate/out/valid-envoyproxy.all.yaml
index 638390ff440..fe1b452f291 100644
--- a/internal/cmd/egctl/testdata/translate/out/valid-envoyproxy.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/valid-envoyproxy.all.yaml
@@ -1,4 +1,5 @@
envoyProxyForGatewayClass:
+ kind: EnvoyProxy
metadata:
creationTimestamp: null
name: example
@@ -13,6 +14,7 @@ envoyProxyForGatewayClass:
type: Kubernetes
status: {}
gatewayClass:
+ kind: GatewayClass
metadata:
creationTimestamp: null
name: eg
@@ -32,7 +34,8 @@ gatewayClass:
status: "True"
type: Accepted
gateways:
-- metadata:
+- kind: Gateway
+ metadata:
creationTimestamp: null
name: eg
namespace: default
diff --git a/internal/cmd/egctl/testdata/validate/invalid-resources.yaml b/internal/cmd/egctl/testdata/validate/invalid-resources.yaml
new file mode 100644
index 00000000000..b7815b10707
--- /dev/null
+++ b/internal/cmd/egctl/testdata/validate/invalid-resources.yaml
@@ -0,0 +1,161 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+ name: eg
+spec:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+ name: eg1
+ namespace: default
+spec:
+ gatewayClassName: eg
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 88888 # invalid port
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+ name: eg2
+ namespace: default
+spec:
+ gatewayClassName: eg
+ listeners:
+ - name: tcp
+ protocol: TCP
+ port: 1234
+ - name: tcp
+ protocol: TCP
+ port: 1234
+ - name: tls-passthrough
+ protocol: TLS
+ port: 8443
+ hostname: foo.com
+ tls:
+ mode: Passthrough
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ kinds:
+ - kind: HTTPRoute
+ group: gateway.networking.k8s.io
+ - name: grpc
+ protocol: HTTP
+ port: 8080
+ allowedRoutes:
+ kinds:
+ - kind: GRPCRoute
+ group: gateway.networking.k8s.io
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: backend
+ namespace: default
+spec:
+ parentRefs:
+ - name: eg
+ hostnames:
+ - ".;'.';[]"
+ rules:
+ - backendRefs:
+ - group: ""
+ kind: Service
+ name: backend
+ port: 3000
+ weight: 1
+ matches:
+ - path:
+ type: PathPrefix
+ value: /
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyPatchPolicy
+metadata:
+ name: ratelimit-patch-policy
+spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
+ type: JSONPatch
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.listener.v3.Listener"
+ # The listener name is of the form //
+ name: default/eg/http
+ operation:
+ op: add
+ path: "/default_filter_chain/filters/0/typed_config/http_filters/0"
+ value:
+ name: "envoy.filters.http.ratelimit"
+ typed_config:
+ "@type": "type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit"
+ domain: "eag-ratelimit"
+ failure_mode_deny: true
+ timeout: 1s
+ rate_limit_service:
+ grpc_service:
+ envoy_grpc:
+ cluster_name: rate-limit-cluster
+ transport_api_version: V3
+ - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
+ # The route name is of the form //
+ name: default/eg/http
+ operation:
+ op: add
+ path: "/virtual_hosts/0/rate_limits"
+ value:
+ - actions:
+ - remote_address: {}
+ - type: "type.googleapis.com/envoy.config.cluster.v3.Cluster"
+ name: rate-limit-cluster
+ operation:
+ op: add
+ path: ""
+ value:
+ name: rate-limit-cluster
+ type: STRICT_DNS
+ connect_timeout: 10s
+ lb_policy: ROUND_ROBIN
+ http2_protocol_options: {}
+ load_assignment:
+ cluster_name: rate-limit-cluster
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: ratelimit.svc.cluster.local
+ port_value: 8081
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend-1
+ namespace: default
+spec:
+ endpoints:
+ - ip:
+ address: a.b.c.d
+ port: 3001
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend-2
+ namespace: default
+spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ - unix:
+ path: test.sock
+ - fqdn:
+ hostname: foo.bar
+ port: 8080
diff --git a/internal/cmd/egctl/translate.go b/internal/cmd/egctl/translate.go
index 2bf4cda177f..7be07c4cfe2 100644
--- a/internal/cmd/egctl/translate.go
+++ b/internal/cmd/egctl/translate.go
@@ -11,9 +11,7 @@ import (
"fmt"
"io"
"os"
- "reflect"
"sort"
- "strings"
adminv3 "github.com/envoyproxy/go-control-plane/envoy/admin/v3"
bootstrapv3 "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3"
@@ -22,19 +20,12 @@ import (
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/known/anypb"
- corev1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "k8s.io/apimachinery/pkg/util/sets"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
- gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/yaml"
- egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/api/v1alpha1/validation"
- "github.com/envoyproxy/gateway/internal/envoygateway"
- "github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/ratelimit"
"github.com/envoyproxy/gateway/internal/xds/bootstrap"
@@ -46,14 +37,12 @@ const (
gatewayAPIType = "gateway-api"
xdsType = "xds"
irType = "ir"
-
- dummyClusterIP = "1.2.3.4"
)
type TranslationResult struct {
- gatewayapi.Resources
- XdsIR gatewayapi.XdsIRMap `json:"xdsIR,omitempty" yaml:"xdsIR,omitempty"`
- InfraIR gatewayapi.InfraIRMap `json:"infraIR,omitempty" yaml:"infraIR,omitempty"`
+ resource.Resources
+ XdsIR resource.XdsIRMap `json:"xdsIR,omitempty" yaml:"xdsIR,omitempty"`
+ InfraIR resource.InfraIRMap `json:"infraIR,omitempty" yaml:"infraIR,omitempty"`
Xds map[string]interface{} `json:"xds,omitempty"`
}
@@ -63,47 +52,48 @@ func newTranslateCommand() *cobra.Command {
addMissingResources bool
outTypes []string
dnsDomain string
+ namespace string
)
translateCommand := &cobra.Command{
Use: "translate",
Short: "Translate Configuration from an input type to an output type",
Example: ` # Translate Gateway API Resources into All xDS Resources.
- egctl experimental translate --from gateway-api --to xds --file
+ egctl experimental translate --from gateway-api --to xds --file -n
# Translate Gateway API Resources into All xDS Resources in JSON output.
- egctl experimental translate --from gateway-api --to xds --type all --output json --file
+ egctl experimental translate --from gateway-api --to xds --type all --output json --file -n
# Translate Gateway API Resources into All xDS Resources in YAML output.
- egctl experimental translate --from gateway-api --to xds --type all --output yaml --file
+ egctl experimental translate --from gateway-api --to xds --type all --output yaml --file -n
# Translate Gateway API Resources into Bootstrap xDS Resources.
- egctl experimental translate --from gateway-api --to xds --type bootstrap --file
+ egctl experimental translate --from gateway-api --to xds --type bootstrap --file -n
# Translate Gateway API Resources into Cluster xDS Resources.
- egctl experimental translate --from gateway-api --to xds --type cluster --file
+ egctl experimental translate --from gateway-api --to xds --type cluster --file -n
# Translate Gateway API Resources into Listener xDS Resources.
- egctl experimental translate --from gateway-api --to xds --type listener --file
+ egctl experimental translate --from gateway-api --to xds --type listener --file -n
# Translate Gateway API Resources into Route xDS Resources.
- egctl experimental translate --from gateway-api --to xds --type route --file
+ egctl experimental translate --from gateway-api --to xds --type route --file -n
# Translate Gateway API Resources into Cluster xDS Resources with short syntax.
- egctl x translate --from gateway-api --to xds -t cluster -o yaml -f
+ egctl x translate --from gateway-api --to xds -t cluster -o yaml -f -n
# Translate Gateway API Resources into All xDS Resources with dummy resources added.
- egctl x translate --from gateway-api --to xds -t cluster --add-missing-resources -f
+ egctl x translate --from gateway-api --to xds -t cluster --add-missing-resources -f -n
# Translate Gateway API Resources into All xDS Resources in YAML output,
# also print the Gateway API Resources with updated status in the same output.
- egctl experimental translate --from gateway-api --to gateway-api,xds --type all --output yaml --file
+ egctl experimental translate --from gateway-api --to gateway-api,xds --type all --output yaml --file -n
# Translate Gateway API Resources into IR in YAML output,
egctl experimental translate --from gateway-api --to ir --output yaml --file
`,
RunE: func(cmd *cobra.Command, args []string) error {
- return translate(cmd.OutOrStdout(), inFile, inType, outTypes, output, resourceType, addMissingResources, dnsDomain)
+ return translate(cmd.OutOrStdout(), inFile, inType, outTypes, output, resourceType, addMissingResources, namespace, dnsDomain)
},
}
@@ -117,6 +107,8 @@ func newTranslateCommand() *cobra.Command {
translateCommand.PersistentFlags().StringVarP(&resourceType, "type", "t", string(AllEnvoyConfigType), getValidResourceTypesStr())
translateCommand.PersistentFlags().BoolVarP(&addMissingResources, "add-missing-resources", "", false, "Provides dummy resources if missed")
translateCommand.PersistentFlags().StringVarP(&dnsDomain, "dns-domain", "", "cluster.local", "DNS domain used by k8s services, default is cluster.local")
+ translateCommand.PersistentFlags().StringVarP(&namespace, "namespace", "n", "envoy-gateway-system", "Namespace where envoy gateway is installed.")
+
return translateCommand
}
@@ -220,7 +212,7 @@ func validate(inFile, inType string, outTypes []string, resourceType string) err
return nil
}
-func translate(w io.Writer, inFile, inType string, outTypes []string, output, resourceType string, addMissingResources bool, dnsDomain string) error {
+func translate(w io.Writer, inFile, inType string, outTypes []string, output, resourceType string, addMissingResources bool, namespace, dnsDomain string) error {
if err := validate(inFile, inType, outTypes, resourceType); err != nil {
return err
}
@@ -232,7 +224,7 @@ func translate(w io.Writer, inFile, inType string, outTypes []string, output, re
if inType == gatewayAPIType {
// Unmarshal input
- resources, err := kubernetesYAMLToResources(string(inBytes), addMissingResources)
+ resources, err := resource.LoadResourcesFromYAMLBytes(inBytes, addMissingResources)
if err != nil {
return fmt.Errorf("unable to unmarshal input: %w", err)
}
@@ -247,7 +239,7 @@ func translate(w io.Writer, inFile, inType string, outTypes []string, output, re
}
}
if outType == xdsType {
- res, err := translateGatewayAPIToXds(dnsDomain, resourceType, resources)
+ res, err := translateGatewayAPIToXds(namespace, dnsDomain, resourceType, resources)
if err != nil {
return err
}
@@ -273,7 +265,7 @@ func translate(w io.Writer, inFile, inType string, outTypes []string, output, re
return fmt.Errorf("unable to find translate from input type %s to output type %s", inType, outTypes)
}
-func translateGatewayAPIToIR(resources *gatewayapi.Resources) (*gatewayapi.TranslateResult, error) {
+func translateGatewayAPIToIR(resources *resource.Resources) (*gatewayapi.TranslateResult, error) {
if resources.GatewayClass == nil {
return nil, fmt.Errorf("the GatewayClass resource is required")
}
@@ -300,9 +292,9 @@ func translateGatewayAPIToIR(resources *gatewayapi.Resources) (*gatewayapi.Trans
return result, nil
}
-func translateGatewayAPIToGatewayAPI(resources *gatewayapi.Resources) (gatewayapi.Resources, error) {
+func translateGatewayAPIToGatewayAPI(resources *resource.Resources) (resource.Resources, error) {
if resources.GatewayClass == nil {
- return gatewayapi.Resources{}, fmt.Errorf("the GatewayClass resource is required")
+ return resource.Resources{}, fmt.Errorf("the GatewayClass resource is required")
}
// Translate from Gateway API to Xds IR
@@ -323,6 +315,11 @@ func translateGatewayAPIToGatewayAPI(resources *gatewayapi.Resources) (gatewayap
msg := fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err)
status.SetGatewayClassAccepted(resources.GatewayClass, false, string(gwapiv1.GatewayClassReasonInvalidParameters), msg)
}
+ if err := bootstrap.Validate(resources.EnvoyProxyForGatewayClass.Spec.Bootstrap); err != nil {
+ epInvalid = true
+ msg := fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err)
+ status.SetGatewayClassAccepted(resources.GatewayClass, false, string(gwapiv1.GatewayClassReasonInvalidParameters), msg)
+ }
gRes.EnvoyProxyForGatewayClass = resources.EnvoyProxyForGatewayClass
}
if !epInvalid {
@@ -333,7 +330,7 @@ func translateGatewayAPIToGatewayAPI(resources *gatewayapi.Resources) (gatewayap
return gRes.Resources, nil
}
-func translateGatewayAPIToXds(dnsDomain string, resourceType string, resources *gatewayapi.Resources) (map[string]any, error) {
+func translateGatewayAPIToXds(namespace, dnsDomain string, resourceType string, resources *resource.Resources) (map[string]any, error) {
if resources.GatewayClass == nil {
return nil, fmt.Errorf("the GatewayClass resource is required")
}
@@ -363,7 +360,7 @@ func translateGatewayAPIToXds(dnsDomain string, resourceType string, resources *
xTranslator := &translator.Translator{
// Set some default settings for translation
GlobalRateLimit: &translator.GlobalRateLimitSettings{
- ServiceURL: ratelimit.GetServiceURL("envoy-gateway", dnsDomain),
+ ServiceURL: ratelimit.GetServiceURL(namespace, dnsDomain),
},
}
if resources.EnvoyProxyForGatewayClass != nil {
@@ -429,7 +426,7 @@ func printOutput(w io.Writer, result TranslationResult, output string) error {
}
// constructConfigDump constructs configDump from ResourceVersionTable and BootstrapConfig
-func constructConfigDump(resources *gatewayapi.Resources, tCtx *xds_types.ResourceVersionTable) (*adminv3.ConfigDump, error) {
+func constructConfigDump(resources *resource.Resources, tCtx *xds_types.ResourceVersionTable) (*adminv3.ConfigDump, error) {
globalConfigs := &adminv3.ConfigDump{}
bootstrapConfigs := &adminv3.BootstrapConfigDump{}
proxyBootstrap := &bootstrapv3.Bootstrap{}
@@ -546,427 +543,3 @@ func constructConfigDump(resources *gatewayapi.Resources, tCtx *xds_types.Resour
return globalConfigs, nil
}
-
-func addMissingServices(requiredServices map[string]*corev1.Service, obj interface{}) {
- var objNamespace string
- protocol := corev1.Protocol(gatewayapi.TCPProtocol)
-
- refs := []gwapiv1.BackendRef{}
- switch route := obj.(type) {
- case *gwapiv1.HTTPRoute:
- objNamespace = route.Namespace
- for _, rule := range route.Spec.Rules {
- for _, httpBakcendRef := range rule.BackendRefs {
- refs = append(refs, httpBakcendRef.BackendRef)
- }
- }
- case *gwapiv1.GRPCRoute:
- objNamespace = route.Namespace
- for _, rule := range route.Spec.Rules {
- for _, gRPCBakcendRef := range rule.BackendRefs {
- refs = append(refs, gRPCBakcendRef.BackendRef)
- }
- }
- case *gwapiv1a2.TLSRoute:
- objNamespace = route.Namespace
- for _, rule := range route.Spec.Rules {
- refs = append(refs, rule.BackendRefs...)
- }
- case *gwapiv1a2.TCPRoute:
- objNamespace = route.Namespace
- for _, rule := range route.Spec.Rules {
- refs = append(refs, rule.BackendRefs...)
- }
- case *gwapiv1a2.UDPRoute:
- protocol = gatewayapi.UDPProtocol
- objNamespace = route.Namespace
- for _, rule := range route.Spec.Rules {
- refs = append(refs, rule.BackendRefs...)
- }
- }
-
- for _, ref := range refs {
- if ref.Kind == nil || *ref.Kind != gatewayapi.KindService {
- continue
- }
-
- ns := objNamespace
- if ref.Namespace != nil {
- ns = string(*ref.Namespace)
- }
- name := string(ref.Name)
- key := ns + "/" + name
-
- port := int32(*ref.Port)
- servicePort := corev1.ServicePort{
- Name: fmt.Sprintf("%s-%d", protocol, port),
- Protocol: protocol,
- Port: port,
- }
- if service, found := requiredServices[key]; !found {
- service := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: ns,
- },
- Spec: corev1.ServiceSpec{
- // Just a dummy IP
- ClusterIP: dummyClusterIP,
- Ports: []corev1.ServicePort{servicePort},
- },
- }
- requiredServices[key] = service
- } else {
- inserted := false
- for _, port := range service.Spec.Ports {
- if port.Protocol == servicePort.Protocol && port.Port == servicePort.Port {
- inserted = true
- break
- }
- }
-
- if !inserted {
- service.Spec.Ports = append(service.Spec.Ports, servicePort)
- }
- }
- }
-}
-
-// kubernetesYAMLToResources converts a Kubernetes YAML string into GatewayAPI Resources
-func kubernetesYAMLToResources(str string, addMissingResources bool) (*gatewayapi.Resources, error) {
- resources := gatewayapi.NewResources()
- var useDefaultNamespace bool
- providedNamespaceMap := sets.New[string]()
- requiredNamespaceMap := sets.New[string]()
- yamls := strings.Split(str, "\n---")
- combinedScheme := envoygateway.GetScheme()
- for _, y := range yamls {
- if strings.TrimSpace(y) == "" {
- continue
- }
- var obj map[string]interface{}
- err := yaml.Unmarshal([]byte(y), &obj)
- if err != nil {
- return nil, err
- }
- un := unstructured.Unstructured{Object: obj}
- gvk := un.GroupVersionKind()
- name, namespace := un.GetName(), un.GetNamespace()
- if namespace == "" {
- // When kubectl applies a resource in yaml which doesn't have a namespace,
- // the current namespace is applied. Here we do the same thing before translating
- // the GatewayAPI resource. Otherwise, the resource can't pass the namespace validation
- useDefaultNamespace = true
- namespace = config.DefaultNamespace
- }
- requiredNamespaceMap.Insert(namespace)
- kobj, err := combinedScheme.New(gvk)
- if err != nil {
- return nil, err
- }
- err = combinedScheme.Convert(&un, kobj, nil)
- if err != nil {
- return nil, err
- }
-
- objType := reflect.TypeOf(kobj)
- if objType.Kind() != reflect.Ptr {
- return nil, fmt.Errorf("expected pointer type, but got %s", objType.Kind().String())
- }
- kobjVal := reflect.ValueOf(kobj).Elem()
- spec := kobjVal.FieldByName("Spec")
-
- switch gvk.Kind {
- case gatewayapi.KindEnvoyProxy:
- typedSpec := spec.Interface()
- envoyProxy := &egv1a1.EnvoyProxy{
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: namespace,
- },
- Spec: typedSpec.(egv1a1.EnvoyProxySpec),
- }
- resources.EnvoyProxyForGatewayClass = envoyProxy
- case gatewayapi.KindGatewayClass:
- typedSpec := spec.Interface()
- gatewayClass := &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: namespace,
- },
- Spec: typedSpec.(gwapiv1.GatewayClassSpec),
- }
- // fill controller name by default controller name when gatewayclass controller name empty.
- if gatewayClass.Spec.ControllerName == "" {
- gatewayClass.Spec.ControllerName = egv1a1.GatewayControllerName
- }
- resources.GatewayClass = gatewayClass
- case gatewayapi.KindGateway:
- typedSpec := spec.Interface()
- gateway := &gwapiv1.Gateway{
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: namespace,
- },
- Spec: typedSpec.(gwapiv1.GatewaySpec),
- }
- resources.Gateways = append(resources.Gateways, gateway)
- case gatewayapi.KindTCPRoute:
- typedSpec := spec.Interface()
- tcpRoute := &gwapiv1a2.TCPRoute{
- TypeMeta: metav1.TypeMeta{
- Kind: gatewayapi.KindTCPRoute,
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: namespace,
- },
- Spec: typedSpec.(gwapiv1a2.TCPRouteSpec),
- }
- resources.TCPRoutes = append(resources.TCPRoutes, tcpRoute)
- case gatewayapi.KindUDPRoute:
- typedSpec := spec.Interface()
- udpRoute := &gwapiv1a2.UDPRoute{
- TypeMeta: metav1.TypeMeta{
- Kind: gatewayapi.KindUDPRoute,
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: namespace,
- },
- Spec: typedSpec.(gwapiv1a2.UDPRouteSpec),
- }
- resources.UDPRoutes = append(resources.UDPRoutes, udpRoute)
- case gatewayapi.KindTLSRoute:
- typedSpec := spec.Interface()
- tlsRoute := &gwapiv1a2.TLSRoute{
- TypeMeta: metav1.TypeMeta{
- Kind: gatewayapi.KindTLSRoute,
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: namespace,
- },
- Spec: typedSpec.(gwapiv1a2.TLSRouteSpec),
- }
- resources.TLSRoutes = append(resources.TLSRoutes, tlsRoute)
- case gatewayapi.KindHTTPRoute:
- typedSpec := spec.Interface()
- httpRoute := &gwapiv1.HTTPRoute{
- TypeMeta: metav1.TypeMeta{
- Kind: gatewayapi.KindHTTPRoute,
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: namespace,
- },
- Spec: typedSpec.(gwapiv1.HTTPRouteSpec),
- }
- resources.HTTPRoutes = append(resources.HTTPRoutes, httpRoute)
- case gatewayapi.KindGRPCRoute:
- typedSpec := spec.Interface()
- grpcRoute := &gwapiv1.GRPCRoute{
- TypeMeta: metav1.TypeMeta{
- Kind: gatewayapi.KindGRPCRoute,
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: namespace,
- },
- Spec: typedSpec.(gwapiv1.GRPCRouteSpec),
- }
- resources.GRPCRoutes = append(resources.GRPCRoutes, grpcRoute)
- case gatewayapi.KindNamespace:
- namespace := &corev1.Namespace{
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- },
- }
- resources.Namespaces = append(resources.Namespaces, namespace)
- providedNamespaceMap.Insert(name)
- case gatewayapi.KindService:
- typedSpec := spec.Interface()
- service := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: namespace,
- },
- Spec: typedSpec.(corev1.ServiceSpec),
- }
- if addMissingResources && len(service.Spec.ClusterIP) == 0 {
- // fill with dummy IP when service clusterIP is empty
- service.Spec.ClusterIP = dummyClusterIP
- }
- resources.Services = append(resources.Services, service)
- case egv1a1.KindEnvoyPatchPolicy:
- typedSpec := spec.Interface()
- envoyPatchPolicy := &egv1a1.EnvoyPatchPolicy{
- TypeMeta: metav1.TypeMeta{
- Kind: egv1a1.KindEnvoyPatchPolicy,
- APIVersion: egv1a1.GroupVersion.String(),
- },
- ObjectMeta: metav1.ObjectMeta{
- Namespace: namespace,
- Name: name,
- },
- Spec: typedSpec.(egv1a1.EnvoyPatchPolicySpec),
- }
- resources.EnvoyPatchPolicies = append(resources.EnvoyPatchPolicies, envoyPatchPolicy)
- case egv1a1.KindClientTrafficPolicy:
- typedSpec := spec.Interface()
- clientTrafficPolicy := &egv1a1.ClientTrafficPolicy{
- TypeMeta: metav1.TypeMeta{
- Kind: egv1a1.KindClientTrafficPolicy,
- APIVersion: egv1a1.GroupVersion.String(),
- },
- ObjectMeta: metav1.ObjectMeta{
- Namespace: namespace,
- Name: name,
- },
- Spec: typedSpec.(egv1a1.ClientTrafficPolicySpec),
- }
- resources.ClientTrafficPolicies = append(resources.ClientTrafficPolicies, clientTrafficPolicy)
- case egv1a1.KindBackendTrafficPolicy:
- typedSpec := spec.Interface()
- backendTrafficPolicy := &egv1a1.BackendTrafficPolicy{
- TypeMeta: metav1.TypeMeta{
- Kind: egv1a1.KindBackendTrafficPolicy,
- APIVersion: egv1a1.GroupVersion.String(),
- },
- ObjectMeta: metav1.ObjectMeta{
- Namespace: namespace,
- Name: name,
- },
- Spec: typedSpec.(egv1a1.BackendTrafficPolicySpec),
- }
- resources.BackendTrafficPolicies = append(resources.BackendTrafficPolicies, backendTrafficPolicy)
- case egv1a1.KindSecurityPolicy:
- typedSpec := spec.Interface()
- securityPolicy := &egv1a1.SecurityPolicy{
- TypeMeta: metav1.TypeMeta{
- Kind: egv1a1.KindSecurityPolicy,
- APIVersion: egv1a1.GroupVersion.String(),
- },
- ObjectMeta: metav1.ObjectMeta{
- Namespace: namespace,
- Name: name,
- },
- Spec: typedSpec.(egv1a1.SecurityPolicySpec),
- }
- resources.SecurityPolicies = append(resources.SecurityPolicies, securityPolicy)
- }
- }
-
- if useDefaultNamespace {
- if !providedNamespaceMap.Has(config.DefaultNamespace) {
- namespace := &corev1.Namespace{
- ObjectMeta: metav1.ObjectMeta{
- Name: config.DefaultNamespace,
- },
- }
- resources.Namespaces = append(resources.Namespaces, namespace)
- providedNamespaceMap.Insert(config.DefaultNamespace)
- }
- }
-
- if addMissingResources {
- for ns := range requiredNamespaceMap {
- if !providedNamespaceMap.Has(ns) {
- namespace := &corev1.Namespace{
- ObjectMeta: metav1.ObjectMeta{
- Name: ns,
- },
- }
- resources.Namespaces = append(resources.Namespaces, namespace)
- }
- }
-
- requiredServiceMap := map[string]*corev1.Service{}
- for _, route := range resources.TCPRoutes {
- addMissingServices(requiredServiceMap, route)
- }
- for _, route := range resources.UDPRoutes {
- addMissingServices(requiredServiceMap, route)
- }
- for _, route := range resources.TLSRoutes {
- addMissingServices(requiredServiceMap, route)
- }
- for _, route := range resources.HTTPRoutes {
- addMissingServices(requiredServiceMap, route)
- }
- for _, route := range resources.GRPCRoutes {
- addMissingServices(requiredServiceMap, route)
- }
-
- providedServiceMap := map[string]*corev1.Service{}
- for _, service := range resources.Services {
- providedServiceMap[service.Namespace+"/"+service.Name] = service
- }
-
- for key, service := range requiredServiceMap {
- if provided, found := providedServiceMap[key]; !found {
- resources.Services = append(resources.Services, service)
- } else {
- providedPorts := sets.NewString()
- for _, port := range provided.Spec.Ports {
- portKey := fmt.Sprintf("%s-%d", port.Protocol, port.Port)
- providedPorts.Insert(portKey)
- }
-
- for _, port := range service.Spec.Ports {
- name := fmt.Sprintf("%s-%d", port.Protocol, port.Port)
- if !providedPorts.Has(name) {
- servicePort := corev1.ServicePort{
- Name: name,
- Protocol: port.Protocol,
- Port: port.Port,
- }
- provided.Spec.Ports = append(provided.Spec.Ports, servicePort)
- }
- }
- }
- }
-
- // Add EnvoyProxy if it does not exist
- if resources.EnvoyProxyForGatewayClass == nil {
- if err := addDefaultEnvoyProxy(resources); err != nil {
- return nil, err
- }
- }
- }
-
- return resources, nil
-}
-
-func addDefaultEnvoyProxy(resources *gatewayapi.Resources) error {
- if resources.GatewayClass == nil {
- return fmt.Errorf("the GatewayClass resource is required")
- }
-
- defaultEnvoyProxyName := "default-envoy-proxy"
- namespace := resources.GatewayClass.Namespace
- defaultBootstrapStr, err := bootstrap.GetRenderedBootstrapConfig(nil)
- if err != nil {
- return err
- }
- ep := &egv1a1.EnvoyProxy{
- ObjectMeta: metav1.ObjectMeta{
- Namespace: namespace,
- Name: defaultEnvoyProxyName,
- },
- Spec: egv1a1.EnvoyProxySpec{
- Bootstrap: &egv1a1.ProxyBootstrap{
- Value: defaultBootstrapStr,
- },
- },
- }
- resources.EnvoyProxyForGatewayClass = ep
- ns := gwapiv1.Namespace(namespace)
- resources.GatewayClass.Spec.ParametersRef = &gwapiv1.ParametersReference{
- Group: gwapiv1.Group(egv1a1.GroupVersion.Group),
- Kind: gatewayapi.KindEnvoyProxy,
- Name: defaultEnvoyProxyName,
- Namespace: &ns,
- }
- return nil
-}
diff --git a/internal/cmd/egctl/translate_test.go b/internal/cmd/egctl/translate_test.go
index 43fac41ebdd..e87167ce305 100644
--- a/internal/cmd/egctl/translate_test.go
+++ b/internal/cmd/egctl/translate_test.go
@@ -22,6 +22,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/utils/field"
"github.com/envoyproxy/gateway/internal/utils/file"
)
@@ -287,13 +288,17 @@ func TestTranslate(t *testing.T) {
expect: true,
extraArgs: []string{"--add-missing-resources"},
},
+ {
+ name: "backend-endpoint",
+ from: "gateway-api",
+ to: "gateway-api",
+ expect: true,
+ },
}
flag.Parse()
for _, tc := range testCases {
- tc := tc
-
t.Run(tc.name+"|"+tc.resourceType, func(t *testing.T) {
b := bytes.NewBufferString("")
root := newTranslateCommand()
@@ -364,8 +369,12 @@ func TestTranslate(t *testing.T) {
// want.GatewayClass.Status.SupportedFeatures = status.GatewaySupportedFeatures
// }
- opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime")
- require.Empty(t, cmp.Diff(want, got, opts))
+ opts := []cmp.Option{
+ cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"),
+ cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"),
+ }
+
+ require.Empty(t, cmp.Diff(want, got, opts...))
})
}
}
diff --git a/internal/cmd/egctl/validate.go b/internal/cmd/egctl/validate.go
new file mode 100644
index 00000000000..faae65bdd4a
--- /dev/null
+++ b/internal/cmd/egctl/validate.go
@@ -0,0 +1,71 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package egctl
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+
+ "github.com/spf13/cobra"
+
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
+)
+
+func newValidateCommand() *cobra.Command {
+ var inFile string
+
+ validateCommand := &cobra.Command{
+ Use: "validate",
+ Short: "Validate Gateway API Resources from the given file, return all the errors if got any.",
+ Example: ` # Validate Gateway API Resources
+ egctl x validate -f
+`,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ if len(inFile) == 0 {
+ return fmt.Errorf("-f/--file must be specified")
+ }
+
+ return runValidate(cmd.OutOrStdout(), inFile)
+ },
+ }
+
+ validateCommand.PersistentFlags().StringVarP(&inFile, "file", "f", "", "Location of input file.")
+ if err := validateCommand.MarkPersistentFlagRequired("file"); err != nil {
+ return nil
+ }
+
+ return validateCommand
+}
+
+func runValidate(w io.Writer, inFile string) error {
+ inBytes, err := getInputBytes(inFile)
+ if err != nil {
+ return fmt.Errorf("unable to read input file: %w", err)
+ }
+
+ noErr := true
+ _ = resource.IterYAMLBytes(inBytes, func(yamlByte []byte) error {
+ // Passing each resource as YAML string and get all their errors from local validator.
+ _, err = resource.LoadResourcesFromYAMLBytes(yamlByte, false)
+ if err != nil {
+ noErr = false
+ yamlRows := bytes.Split(yamlByte, []byte("\n"))
+ if len(yamlRows) > 6 {
+ yamlRows = append(yamlRows[:6], []byte("..."))
+ }
+ _, err = fmt.Fprintf(w, "%s\n%s\n\n",
+ bytes.Join(yamlRows, []byte("\n")), err.Error())
+ }
+ return nil
+ })
+
+ if noErr {
+ _, err = fmt.Fprintln(w, "\033[32mOK\033[0m")
+ }
+
+ return err
+}
diff --git a/internal/cmd/egctl/validate_test.go b/internal/cmd/egctl/validate_test.go
new file mode 100644
index 00000000000..bbb18605e12
--- /dev/null
+++ b/internal/cmd/egctl/validate_test.go
@@ -0,0 +1,94 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package egctl
+
+import (
+ "bytes"
+ "context"
+ "io"
+ "path"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestRunValidate(t *testing.T) {
+ testCases := []struct {
+ name string
+ output string
+ }{
+ {
+ name: "invalid-resources",
+ output: `apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+ name: eg1
+ namespace: default
+spec:
+...
+local validation error: Gateway.gateway.networking.k8s.io "eg1" is invalid: spec.listeners[0].port: Invalid value: 88888: spec.listeners[0].port in body should be less than or equal to 65535
+
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+ name: eg2
+ namespace: default
+spec:
+...
+local validation error: Gateway.gateway.networking.k8s.io "eg2" is invalid: [spec.listeners[1]: Duplicate value: map[string]interface {}{"name":"tcp"}, spec.listeners: Invalid value: "array": Listener name must be unique within the Gateway, spec.listeners: Invalid value: "array": Combination of port, protocol and hostname must be unique for each listener]
+
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: backend
+ namespace: default
+spec:
+...
+local validation error: HTTPRoute.gateway.networking.k8s.io "backend" is invalid: spec.hostnames[0]: Invalid value: ".;'.';[]": spec.hostnames[0] in body should match '^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$'
+
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend-1
+ namespace: default
+spec:
+...
+local validation error: Backend.gateway.envoyproxy.io "backend-1" is invalid: spec.endpoints[0].ip.address: Invalid value: "a.b.c.d": spec.endpoints[0].ip.address in body should match '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(([0-9a-fA-F]{1,4}:){1,7}[0-9a-fA-F]{1,4}|::|(([0-9a-fA-F]{1,4}:){0,5})?(:[0-9a-fA-F]{1,4}){1,2})$'
+
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend-2
+ namespace: default
+spec:
+...
+local validation error: Backend.gateway.envoyproxy.io "backend-2" is invalid: spec.endpoints: Invalid value: "array": fqdn addresses cannot be mixed with other address types
+
+`,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ b := bytes.NewBufferString("")
+ root := newValidateCommand()
+ root.SetOut(b)
+ root.SetErr(b)
+ args := []string{
+ "--file",
+ path.Join("testdata", "validate", tc.name+".yaml"),
+ }
+
+ root.SetArgs(args)
+ err := root.ExecuteContext(context.Background())
+ require.NoError(t, err)
+
+ out, err := io.ReadAll(b)
+ require.NoError(t, err)
+ require.Equal(t, tc.output, string(out))
+ })
+ }
+}
diff --git a/internal/cmd/egctl/version.go b/internal/cmd/egctl/version.go
index 5cab0035358..7492effeee6 100644
--- a/internal/cmd/egctl/version.go
+++ b/internal/cmd/egctl/version.go
@@ -99,7 +99,6 @@ func versions(w io.Writer, containerName, output string, remote bool) error {
}
for _, pod := range pods.Items {
- pod := pod
if pod.Status.Phase != "Running" {
fmt.Fprintf(w, "WARN: pod %s/%s is not running, skipping it.", pod.Namespace, pod.Name)
diff --git a/internal/cmd/envoy.go b/internal/cmd/envoy.go
index 20cf95bb412..87eccf8a520 100644
--- a/internal/cmd/envoy.go
+++ b/internal/cmd/envoy.go
@@ -40,10 +40,10 @@ func getShutdownCommand() *cobra.Command {
},
}
- cmd.PersistentFlags().DurationVar(&drainTimeout, "drain-timeout", 600*time.Second,
+ cmd.PersistentFlags().DurationVar(&drainTimeout, "drain-timeout", 60*time.Second,
"Graceful shutdown timeout. This should be less than the pod's terminationGracePeriodSeconds.")
- cmd.PersistentFlags().DurationVar(&minDrainDuration, "min-drain-duration", 5*time.Second,
+ cmd.PersistentFlags().DurationVar(&minDrainDuration, "min-drain-duration", 10*time.Second,
"Minimum drain duration allowing time for endpoint deprogramming to complete.")
cmd.PersistentFlags().IntVar(&exitAtConnections, "exit-at-connections", 0,
diff --git a/internal/cmd/envoy/shutdown_manager.go b/internal/cmd/envoy/shutdown_manager.go
index 9f2702cff33..e0b8204a61d 100644
--- a/internal/cmd/envoy/shutdown_manager.go
+++ b/internal/cmd/envoy/shutdown_manager.go
@@ -114,7 +114,7 @@ func shutdownReadyHandler(w http.ResponseWriter, readyTimeout time.Duration, rea
}
// Shutdown is called from a preStop hook on the shutdown-manager container where
-// it will initiate a graceful drain sequence on the Envoy proxy and block until
+// it will initiate a drain sequence on the Envoy proxy and block until
// connections are drained or a timeout is exceeded.
func Shutdown(drainTimeout time.Duration, minDrainDuration time.Duration, exitAtConnections int) error {
startTime := time.Now()
@@ -125,7 +125,7 @@ func Shutdown(drainTimeout time.Duration, minDrainDuration time.Duration, exitAt
logger = logging.FileLogger("/proc/1/fd/1", "shutdown-manager", egv1a1.LogLevelInfo)
}
- logger.Info(fmt.Sprintf("initiating graceful drain with %.0f second minimum drain period and %.0f second timeout",
+ logger.Info(fmt.Sprintf("initiating drain with %.0f second minimum drain period and %.0f second timeout",
minDrainDuration.Seconds(), drainTimeout.Seconds()))
// Start failing active health checks
@@ -133,11 +133,6 @@ func Shutdown(drainTimeout time.Duration, minDrainDuration time.Duration, exitAt
logger.Error(err, "error failing active health checks")
}
- // Initiate graceful drain sequence
- if err := postEnvoyAdminAPI("drain_listeners?graceful&skip_exit"); err != nil {
- logger.Error(err, "error initiating graceful drain")
- }
-
// Poll total connections from Envoy admin API until minimum drain period has
// been reached and total connections reaches threshold or timeout is exceeded
for {
@@ -154,10 +149,10 @@ func Shutdown(drainTimeout time.Duration, minDrainDuration time.Duration, exitAt
}
if elapsedTime > drainTimeout {
- logger.Info("graceful drain sequence timeout exceeded")
+ logger.Info("drain sequence timeout exceeded")
break
} else if allowedToExit && conn != nil && *conn <= exitAtConnections {
- logger.Info("graceful drain sequence completed")
+ logger.Info("drain sequence completed")
break
}
@@ -176,7 +171,7 @@ func Shutdown(drainTimeout time.Duration, minDrainDuration time.Duration, exitAt
// postEnvoyAdminAPI sends a POST request to the Envoy admin API
func postEnvoyAdminAPI(path string) error {
if resp, err := http.Post(fmt.Sprintf("http://%s:%d/%s",
- bootstrap.EnvoyAdminAddress, bootstrap.EnvoyAdminPort, path), "application/json", nil); err != nil {
+ "localhost", bootstrap.EnvoyAdminPort, path), "application/json", nil); err != nil {
return err
} else {
defer resp.Body.Close()
@@ -192,7 +187,7 @@ func postEnvoyAdminAPI(path string) error {
func getTotalConnections() (*int, error) {
// Send request to Envoy admin API to retrieve server.total_connections stat
if resp, err := http.Get(fmt.Sprintf("http://%s:%d//stats?filter=^server\\.total_connections$&format=json",
- bootstrap.EnvoyAdminAddress, bootstrap.EnvoyAdminPort)); err != nil {
+ "localhost", bootstrap.EnvoyAdminPort)); err != nil {
return nil, err
} else {
defer resp.Body.Close()
diff --git a/internal/cmd/server.go b/internal/cmd/server.go
index e4bf36a5ae5..a4c9d3e9713 100644
--- a/internal/cmd/server.go
+++ b/internal/cmd/server.go
@@ -6,12 +6,17 @@
package cmd
import (
+ "context"
+
"github.com/spf13/cobra"
ctrl "sigs.k8s.io/controller-runtime"
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/admin"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/envoygateway/config/loader"
extensionregistry "github.com/envoyproxy/gateway/internal/extension/registry"
+ "github.com/envoyproxy/gateway/internal/extension/types"
gatewayapirunner "github.com/envoyproxy/gateway/internal/gatewayapi/runner"
ratelimitrunner "github.com/envoyproxy/gateway/internal/globalratelimit/runner"
infrarunner "github.com/envoyproxy/gateway/internal/infrastructure/runner"
@@ -49,6 +54,20 @@ func server() error {
return err
}
+ ctx := ctrl.SetupSignalHandler()
+ hook := func(c context.Context, cfg *config.Server) error {
+ cfg.Logger.Info("Setup runners")
+ if err := setupRunners(c, cfg); err != nil {
+ cfg.Logger.Error(err, "failed to setup runners")
+ return err
+ }
+ return nil
+ }
+ l := loader.New(cfgPath, cfg, hook)
+ if err := l.Start(ctx); err != nil {
+ return err
+ }
+
// Init eg admin servers.
if err := admin.Init(cfg); err != nil {
return err
@@ -58,10 +77,10 @@ func server() error {
return err
}
- // init eg runners.
- if err := setupRunners(cfg); err != nil {
- return err
- }
+ // Wait exit signal
+ <-ctx.Done()
+
+ cfg.Logger.Info("shutting down")
return nil
}
@@ -108,28 +127,27 @@ func getConfigByPath(cfgPath string) (*config.Server, error) {
// setupRunners starts all the runners required for the Envoy Gateway to
// fulfill its tasks.
-func setupRunners(cfg *config.Server) error {
- // TODO - Setup a Config Manager
- // https://github.com/envoyproxy/gateway/issues/43
- ctx := ctrl.SetupSignalHandler()
-
+func setupRunners(ctx context.Context, cfg *config.Server) (err error) {
// Setup the Extension Manager
- extMgr, err := extensionregistry.NewManager(cfg)
- if err != nil {
- return err
+ var extMgr types.Manager
+ if cfg.EnvoyGateway.Provider.Type == egv1a1.ProviderTypeKubernetes {
+ extMgr, err = extensionregistry.NewManager(cfg)
+ if err != nil {
+ return err
+ }
}
pResources := new(message.ProviderResources)
// Start the Provider Service
// It fetches the resources from the configured provider type
- // and publishes it
+ // and publishes it.
// It also subscribes to status resources and once it receives
// a status resource back, it writes it out.
providerRunner := providerrunner.New(&providerrunner.Config{
Server: *cfg,
ProviderResources: pResources,
})
- if err := providerRunner.Start(ctx); err != nil {
+ if err = providerRunner.Start(ctx); err != nil {
return err
}
@@ -145,7 +163,7 @@ func setupRunners(cfg *config.Server) error {
InfraIR: infraIR,
ExtensionManager: extMgr,
})
- if err := gwRunner.Start(ctx); err != nil {
+ if err = gwRunner.Start(ctx); err != nil {
return err
}
@@ -160,7 +178,7 @@ func setupRunners(cfg *config.Server) error {
ExtensionManager: extMgr,
ProviderResources: pResources,
})
- if err := xdsTranslatorRunner.Start(ctx); err != nil {
+ if err = xdsTranslatorRunner.Start(ctx); err != nil {
return err
}
@@ -171,7 +189,7 @@ func setupRunners(cfg *config.Server) error {
Server: *cfg,
InfraIR: infraIR,
})
- if err := infraRunner.Start(ctx); err != nil {
+ if err = infraRunner.Start(ctx); err != nil {
return err
}
@@ -182,7 +200,7 @@ func setupRunners(cfg *config.Server) error {
Server: *cfg,
Xds: xds,
})
- if err := xdsServerRunner.Start(ctx); err != nil {
+ if err = xdsServerRunner.Start(ctx); err != nil {
return err
}
@@ -194,7 +212,7 @@ func setupRunners(cfg *config.Server) error {
Server: *cfg,
XdsIR: xdsIR,
})
- if err := rateLimitRunner.Start(ctx); err != nil {
+ if err = rateLimitRunner.Start(ctx); err != nil {
return err
}
}
@@ -207,11 +225,13 @@ func setupRunners(cfg *config.Server) error {
infraIR.Close()
xds.Close()
- cfg.Logger.Info("shutting down")
+ cfg.Logger.Info("runners are shutting down")
- // Close connections to extension services
- if mgr, ok := extMgr.(*extensionregistry.Manager); ok {
- mgr.CleanupHookConns()
+ if extMgr != nil {
+ // Close connections to extension services
+ if mgr, ok := extMgr.(*extensionregistry.Manager); ok {
+ mgr.CleanupHookConns()
+ }
}
return nil
diff --git a/internal/cmd/server_test.go b/internal/cmd/server_test.go
index dffe10670c9..4ce4178dbfd 100644
--- a/internal/cmd/server_test.go
+++ b/internal/cmd/server_test.go
@@ -52,7 +52,6 @@ func TestGetConfigValidate(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
file, err := os.CreateTemp("", "config")
require.NoError(t, err)
diff --git a/internal/crypto/cert_load.go b/internal/crypto/cert_load.go
new file mode 100644
index 00000000000..f00dec1d9a3
--- /dev/null
+++ b/internal/crypto/cert_load.go
@@ -0,0 +1,57 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package crypto
+
+import (
+ "crypto/rand"
+ "crypto/tls"
+ "crypto/x509"
+ "fmt"
+ "os"
+)
+
+// LoadTLSConfig returns TLSConfig form certificates.
+func LoadTLSConfig(tlsCrt, tlsKey, caCrt string) (*tls.Config, error) {
+ loadConfig := func() (*tls.Config, error) {
+ cert, err := tls.LoadX509KeyPair(tlsCrt, tlsKey)
+ if err != nil {
+ return nil, err
+ }
+
+ // Load the CA cert.
+ ca, err := os.ReadFile(caCrt)
+ if err != nil {
+ return nil, err
+ }
+
+ certPool := x509.NewCertPool()
+ if !certPool.AppendCertsFromPEM(ca) {
+ return nil, fmt.Errorf("failed to parse CA certificate")
+ }
+
+ return &tls.Config{
+ Certificates: []tls.Certificate{cert},
+ NextProtos: []string{"h2"},
+ ClientAuth: tls.RequireAndVerifyClientCert,
+ ClientCAs: certPool,
+ MinVersion: tls.VersionTLS13,
+ }, nil
+ }
+
+ // Attempt to load certificates and key to catch configuration errors early.
+ if _, err := loadConfig(); err != nil {
+ return nil, err
+ }
+
+ return &tls.Config{
+ MinVersion: tls.VersionTLS13,
+ ClientAuth: tls.RequireAndVerifyClientCert,
+ Rand: rand.Reader,
+ GetConfigForClient: func(*tls.ClientHelloInfo) (*tls.Config, error) {
+ return loadConfig()
+ },
+ }, nil
+}
diff --git a/internal/envoygateway/config/config.go b/internal/envoygateway/config/config.go
index c842c184e4c..af05dac0753 100644
--- a/internal/envoygateway/config/config.go
+++ b/internal/envoygateway/config/config.go
@@ -7,6 +7,7 @@ package config
import (
"errors"
+ "sync"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/api/v1alpha1/validation"
@@ -37,19 +38,22 @@ type Server struct {
// Logger is the logr implementation used by Envoy Gateway.
Logger logging.Logger
// Elected chan is used to signal what a leader is elected
- Elected chan struct{}
+ Elected *sync.WaitGroup
}
// New returns a Server with default parameters.
func New() (*Server, error) {
- return &Server{
+ server := &Server{
EnvoyGateway: egv1a1.DefaultEnvoyGateway(),
Namespace: env.Lookup("ENVOY_GATEWAY_NAMESPACE", DefaultNamespace),
DNSDomain: env.Lookup("KUBERNETES_CLUSTER_DOMAIN", DefaultDNSDomain),
// the default logger
Logger: logging.DefaultLogger(egv1a1.LogLevelInfo),
- Elected: make(chan struct{}),
- }, nil
+ Elected: &sync.WaitGroup{},
+ }
+ // Block the tasks that are waiting for the leader to be elected
+ server.Elected.Add(1)
+ return server, nil
}
// Validate validates a Server config.
diff --git a/internal/envoygateway/config/config_test.go b/internal/envoygateway/config/config_test.go
index 2b3f461f762..59bba129434 100644
--- a/internal/envoygateway/config/config_test.go
+++ b/internal/envoygateway/config/config_test.go
@@ -63,7 +63,6 @@ func TestValidate(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := tc.cfg.Validate()
if !tc.expect {
diff --git a/internal/envoygateway/config/decoder_test.go b/internal/envoygateway/config/decoder_test.go
index 67520f2e5dd..5bbbb959ed7 100644
--- a/internal/envoygateway/config/decoder_test.go
+++ b/internal/envoygateway/config/decoder_test.go
@@ -347,7 +347,6 @@ func TestDecode(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.in, func(t *testing.T) {
eg, err := Decode(tc.in)
if tc.expect {
diff --git a/internal/envoygateway/config/loader/configloader.go b/internal/envoygateway/config/loader/configloader.go
new file mode 100644
index 00000000000..9523c7a432e
--- /dev/null
+++ b/internal/envoygateway/config/loader/configloader.go
@@ -0,0 +1,113 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package loader
+
+import (
+ "context"
+ "time"
+
+ "github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/filewatcher"
+ "github.com/envoyproxy/gateway/internal/logging"
+)
+
+type HookFunc func(c context.Context, cfg *config.Server) error
+
+type Loader struct {
+ cfgPath string
+ cfg *config.Server
+ logger logging.Logger
+ cancel context.CancelFunc
+ hook HookFunc
+
+ w filewatcher.FileWatcher
+}
+
+func New(cfgPath string, cfg *config.Server, f HookFunc) *Loader {
+ return &Loader{
+ cfgPath: cfgPath,
+ cfg: cfg,
+ logger: cfg.Logger.WithName("config-loader"),
+ hook: f,
+ w: filewatcher.NewWatcher(),
+ }
+}
+
+func (r *Loader) Start(ctx context.Context) error {
+ r.runHook()
+
+ if r.cfgPath == "" {
+ r.logger.Info("no config file provided, skipping config watcher")
+ return nil
+ }
+
+ r.logger.Info("watching for changes to the EnvoyGateway configuration", "path", r.cfgPath)
+ if err := r.w.Add(r.cfgPath); err != nil {
+ r.logger.Error(err, "failed to add config file to watcher")
+ return err
+ }
+
+ go func() {
+ defer func() {
+ _ = r.w.Close()
+ }()
+ for {
+ select {
+ case e := <-r.w.Events(r.cfgPath):
+ r.logger.Info("received fsnotify events", "name", e.Name, "op", e.Op.String())
+
+ // Load the config file.
+ eg, err := config.Decode(r.cfgPath)
+ if err != nil {
+ r.logger.Info("failed to decode config file", "name", r.cfgPath, "error", err)
+ // TODO: add a metric for this?
+ continue
+ }
+ // Set defaults for unset fields
+ eg.SetEnvoyGatewayDefaults()
+ r.cfg.EnvoyGateway = eg
+ // update cfg logger
+ eg.Logging.SetEnvoyGatewayLoggingDefaults()
+ r.cfg.Logger = logging.NewLogger(eg.Logging)
+
+ // cancel last
+ if r.cancel != nil {
+ r.cancel()
+ }
+
+ // TODO: we need to make sure that all runners are stopped, before we start the new ones
+ // Otherwise we might end up with error listening on:8081
+ time.Sleep(3 * time.Second)
+
+ r.runHook()
+ case err := <-r.w.Errors(r.cfgPath):
+ r.logger.Error(err, "watcher error")
+ case <-ctx.Done():
+ if r.cancel != nil {
+ r.cancel()
+ }
+ return
+ }
+ }
+ }()
+
+ return nil
+}
+
+func (r *Loader) runHook() {
+ if r.hook == nil {
+ return
+ }
+
+ r.logger.Info("running hook")
+ c, cancel := context.WithCancel(context.TODO())
+ r.cancel = cancel
+ go func(ctx context.Context) {
+ if err := r.hook(ctx, r.cfg); err != nil {
+ r.logger.Error(err, "hook error")
+ }
+ }(c)
+}
diff --git a/internal/envoygateway/config/loader/configloader_test.go b/internal/envoygateway/config/loader/configloader_test.go
new file mode 100644
index 00000000000..d0420df0f5f
--- /dev/null
+++ b/internal/envoygateway/config/loader/configloader_test.go
@@ -0,0 +1,59 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package loader
+
+import (
+ "context"
+ _ "embed"
+ "os"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "github.com/envoyproxy/gateway/internal/envoygateway/config"
+)
+
+var (
+ //go:embed testdata/default.yaml
+ defaultConfig string
+ //go:embed testdata/enable-redis.yaml
+ redisConfig string
+)
+
+func TestConfigLoader(t *testing.T) {
+ tmpDir, err := os.MkdirTemp("", "envoy-gateway-configloader-test")
+ require.NoError(t, err)
+ defer func(path string) {
+ _ = os.RemoveAll(path)
+ }(tmpDir)
+
+ cfgPath := tmpDir + "/config.yaml"
+ require.NoError(t, os.WriteFile(cfgPath, []byte(defaultConfig), 0o600))
+ s, err := config.New()
+ require.NoError(t, err)
+
+ ctx, cancel := context.WithCancel(context.TODO())
+ defer func() {
+ cancel()
+ }()
+
+ changed := 0
+ loader := New(cfgPath, s, func(_ context.Context, cfg *config.Server) error {
+ changed++
+ t.Logf("config changed %d times", changed)
+ if changed > 1 {
+ cancel()
+ }
+ return nil
+ })
+
+ require.NoError(t, loader.Start(ctx))
+ go func() {
+ _ = os.WriteFile(cfgPath, []byte(redisConfig), 0o600)
+ }()
+
+ <-ctx.Done()
+}
diff --git a/internal/envoygateway/config/loader/testdata/default.yaml b/internal/envoygateway/config/loader/testdata/default.yaml
new file mode 100644
index 00000000000..20463f848e1
--- /dev/null
+++ b/internal/envoygateway/config/loader/testdata/default.yaml
@@ -0,0 +1,24 @@
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyGateway
+gateway:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+logging:
+ level:
+ default: info
+provider:
+ kubernetes:
+ rateLimitDeployment:
+ container:
+ image: docker.io/envoyproxy/ratelimit:master
+ patch:
+ type: StrategicMerge
+ value:
+ spec:
+ template:
+ spec:
+ containers:
+ - imagePullPolicy: IfNotPresent
+ name: envoy-ratelimit
+ shutdownManager:
+ image: docker.io/envoyproxy/gateway-dev:latest
+ type: Kubernetes
diff --git a/internal/envoygateway/config/loader/testdata/enable-redis.yaml b/internal/envoygateway/config/loader/testdata/enable-redis.yaml
new file mode 100644
index 00000000000..ed2218ab5ab
--- /dev/null
+++ b/internal/envoygateway/config/loader/testdata/enable-redis.yaml
@@ -0,0 +1,14 @@
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyGateway
+provider:
+ type: Kubernetes
+gateway:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+extensionApis:
+ enableEnvoyPatchPolicy: true
+ enableBackend: true
+rateLimit:
+ backend:
+ type: Redis
+ redis:
+ url: redis.redis-system.svc.cluster.local:6379
diff --git a/internal/extension/registry/extension_manager.go b/internal/extension/registry/extension_manager.go
index 918c9a7c018..cf4b86d3d08 100644
--- a/internal/extension/registry/extension_manager.go
+++ b/internal/extension/registry/extension_manager.go
@@ -11,6 +11,7 @@ import (
"errors"
"fmt"
"net"
+ "strconv"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
@@ -123,13 +124,13 @@ func getExtensionServerAddress(service *egv1a1.ExtensionService) string {
var serverAddr string
switch {
case service.FQDN != nil:
- serverAddr = fmt.Sprintf("%s:%d", service.FQDN.Hostname, service.FQDN.Port)
+ serverAddr = net.JoinHostPort(service.FQDN.Hostname, strconv.Itoa(int(service.FQDN.Port)))
case service.IP != nil:
- serverAddr = fmt.Sprintf("%s:%d", service.IP.Address, service.IP.Port)
+ serverAddr = net.JoinHostPort(service.IP.Address, strconv.Itoa(int(service.IP.Port)))
case service.Unix != nil:
serverAddr = fmt.Sprintf("unix://%s", service.Unix.Path)
case service.Host != "":
- serverAddr = fmt.Sprintf("%s:%d", service.Host, service.Port)
+ serverAddr = net.JoinHostPort(service.Host, strconv.Itoa(int(service.Port)))
}
return serverAddr
}
diff --git a/internal/extension/registry/extension_manager_test.go b/internal/extension/registry/extension_manager_test.go
index f64160ed5ca..a6cd9751d2e 100644
--- a/internal/extension/registry/extension_manager_test.go
+++ b/internal/extension/registry/extension_manager_test.go
@@ -65,7 +65,6 @@ func TestGetExtensionServerAddress(t *testing.T) {
}
for _, tc := range tests {
- tc := tc
t.Run(tc.Name, func(t *testing.T) {
out := getExtensionServerAddress(tc.Service)
require.Equal(t, tc.Expected, out)
diff --git a/internal/filewatcher/filewatcher.go b/internal/filewatcher/filewatcher.go
new file mode 100644
index 00000000000..b7b5555aee7
--- /dev/null
+++ b/internal/filewatcher/filewatcher.go
@@ -0,0 +1,186 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package filewatcher
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "sync"
+
+ "github.com/fsnotify/fsnotify"
+)
+
+// FileWatcher is an interface that watches a set of files,
+// delivering events to related channel.
+type FileWatcher interface {
+ Add(path string) error
+ Remove(path string) error
+ Close() error
+ Events(path string) chan fsnotify.Event
+ Errors(path string) chan error
+}
+
+type fileWatcher struct {
+ mu sync.RWMutex
+
+ // The watcher maintain a map of workers,
+ // keyed by watched dir (parent dir of watched files).
+ workers map[string]*workerState
+
+ funcs *patchTable
+}
+
+type workerState struct {
+ worker *worker
+ count int
+}
+
+// functions that can be replaced in a test setting
+type patchTable struct {
+ newWatcher func() (*fsnotify.Watcher, error)
+ addWatcherPath func(*fsnotify.Watcher, string) error
+}
+
+// NewWatcher return with a FileWatcher instance that implemented with fsnotify.
+func NewWatcher() FileWatcher {
+ return &fileWatcher{
+ workers: map[string]*workerState{},
+
+ // replaceable functions for tests
+ funcs: &patchTable{
+ newWatcher: fsnotify.NewWatcher,
+ addWatcherPath: func(watcher *fsnotify.Watcher, path string) error {
+ return watcher.Add(path)
+ },
+ },
+ }
+}
+
+// Close releases all resources associated with the watcher
+func (fw *fileWatcher) Close() error {
+ fw.mu.Lock()
+ defer fw.mu.Unlock()
+
+ for _, ws := range fw.workers {
+ ws.worker.terminate()
+ }
+ fw.workers = nil
+
+ return nil
+}
+
+// Add a path to watch
+func (fw *fileWatcher) Add(path string) error {
+ fw.mu.Lock()
+ defer fw.mu.Unlock()
+
+ ws, cleanedPath, _, err := fw.getWorker(path)
+ if err != nil {
+ return err
+ }
+
+ if err = ws.worker.addPath(cleanedPath); err == nil {
+ ws.count++
+ }
+
+ return err
+}
+
+func (fw *fileWatcher) Remove(path string) error {
+ fw.mu.Lock()
+ defer fw.mu.Unlock()
+
+ ws, cleanedPath, parentPath, err := fw.getWorker(path)
+ if err != nil {
+ return err
+ }
+
+ if err = ws.worker.removePath(cleanedPath); err == nil {
+ ws.count--
+ if ws.count == 0 {
+ ws.worker.terminate()
+ delete(fw.workers, parentPath)
+ }
+ }
+
+ return err
+}
+
+// Events returns an event notification channel for a path
+func (fw *fileWatcher) Events(path string) chan fsnotify.Event {
+ fw.mu.RLock()
+ defer fw.mu.RUnlock()
+
+ ws, cleanedPath, err := fw.findWorker(path)
+ if err != nil {
+ return nil
+ }
+
+ return ws.worker.eventChannel(cleanedPath)
+}
+
+// Errors returns an error notification channel for a path
+func (fw *fileWatcher) Errors(path string) chan error {
+ fw.mu.RLock()
+ defer fw.mu.RUnlock()
+
+ ws, cleanedPath, err := fw.findWorker(path)
+ if err != nil {
+ return nil
+ }
+
+ return ws.worker.errorChannel(cleanedPath)
+}
+
+func (fw *fileWatcher) getWorker(path string) (*workerState, string, string, error) {
+ if fw.workers == nil {
+ return nil, "", "", errors.New("using a closed watcher")
+ }
+
+ cleanedPath, parentPath := getPath(path)
+ ws, workerExists := fw.workers[parentPath]
+ if !workerExists {
+ wk, err := newWorker(parentPath, fw.funcs)
+ if err != nil {
+ return nil, "", "", err
+ }
+
+ ws = &workerState{
+ worker: wk,
+ }
+
+ fw.workers[parentPath] = ws
+ }
+
+ return ws, cleanedPath, parentPath, nil
+}
+
+func (fw *fileWatcher) findWorker(path string) (*workerState, string, error) {
+ if fw.workers == nil {
+ return nil, "", errors.New("using a closed watcher")
+ }
+
+ cleanedPath, parentPath := getPath(path)
+
+ ws, workerExists := fw.workers[parentPath]
+ if !workerExists {
+ return nil, "", fmt.Errorf("no path registered for %s", path)
+ }
+
+ return ws, cleanedPath, nil
+}
+
+func getPath(path string) (cleanedPath, parentPath string) {
+ cleanedPath = filepath.Clean(path)
+ parentPath, _ = filepath.Split(cleanedPath)
+ if f, err := os.Lstat(cleanedPath); err == nil && f.IsDir() {
+ parentPath = cleanedPath
+ }
+
+ return
+}
diff --git a/internal/filewatcher/filewatcher_test.go b/internal/filewatcher/filewatcher_test.go
new file mode 100644
index 00000000000..5b451fa0df7
--- /dev/null
+++ b/internal/filewatcher/filewatcher_test.go
@@ -0,0 +1,356 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package filewatcher
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "os/exec"
+ "path"
+ "runtime"
+ "sync"
+ "testing"
+ "time"
+
+ "github.com/fsnotify/fsnotify"
+ "github.com/stretchr/testify/require"
+)
+
+func newWatchFile(t *testing.T) string {
+ watchDir := t.TempDir()
+ watchFile := path.Join(watchDir, "test.conf")
+ err := os.WriteFile(watchFile, []byte("foo: bar\n"), 0o600)
+ require.NoError(t, err)
+
+ return watchFile
+}
+
+func newWatchFileThatDoesNotExist(t *testing.T) string {
+ watchDir := t.TempDir()
+
+ watchFile := path.Join(watchDir, "test.conf")
+
+ return watchFile
+}
+
+// newTwoWatchFile returns with two watch files that exist in the same base dir.
+func newTwoWatchFile(t *testing.T) (string, string) {
+ watchDir := t.TempDir()
+
+ watchFile1 := path.Join(watchDir, "test1.conf")
+ err := os.WriteFile(watchFile1, []byte("foo: bar\n"), 0o600)
+ require.NoError(t, err)
+
+ watchFile2 := path.Join(watchDir, "test2.conf")
+ err = os.WriteFile(watchFile2, []byte("foo: baz\n"), 0o600)
+ require.NoError(t, err)
+
+ return watchFile1, watchFile2
+}
+
+// newSymlinkedWatchFile simulates the behavior of k8s configmap/secret.
+// Path structure looks like:
+//
+// /test.conf
+// ^
+// |
+//
+// /data/test.conf
+//
+// ^
+// |
+//
+// /data1/test.conf
+func newSymlinkedWatchFile(t *testing.T) (string, string) {
+ watchDir := t.TempDir()
+
+ dataDir1 := path.Join(watchDir, "data1")
+ err := os.Mkdir(dataDir1, 0o777)
+ require.NoError(t, err)
+
+ realTestFile := path.Join(dataDir1, "test.conf")
+ t.Logf("Real test file location: %s\n", realTestFile)
+ err = os.WriteFile(realTestFile, []byte("foo: bar\n"), 0o600)
+ require.NoError(t, err)
+
+ // Now, symlink the tmp `data1` dir to `data` in the baseDir
+ require.NoError(t, os.Symlink(dataDir1, path.Join(watchDir, "data")))
+ // And link the `/datadir/test.conf` to `/test.conf`
+ watchFile := path.Join(watchDir, "test.conf")
+ require.NoError(t, os.Symlink(path.Join(watchDir, "data", "test.conf"), watchFile))
+ t.Logf("Watch file location: %s\n", path.Join(watchDir, "test.conf"))
+ return watchDir, watchFile
+}
+
+func TestWatchFile(t *testing.T) {
+ t.Run("file content changed", func(t *testing.T) {
+ // Given a file being watched
+ watchFile := newWatchFile(t)
+ _, err := os.Stat(watchFile)
+ require.NoError(t, err)
+
+ w := NewWatcher()
+ require.NoError(t, w.Add(watchFile))
+ events := w.Events(watchFile)
+
+ wg := sync.WaitGroup{}
+ wg.Add(1)
+ go func() {
+ <-events
+ wg.Done()
+ }()
+
+ // Overwriting the file and waiting its event to be received.
+ err = os.WriteFile(watchFile, []byte("foo: baz\n"), 0o600)
+ require.NoError(t, err)
+ wg.Wait()
+
+ _ = w.Close()
+ })
+
+ t.Run("link to real file changed (for k8s configmap/secret path)", func(t *testing.T) {
+ // skip if not executed on Linux
+ if runtime.GOOS != "linux" {
+ t.Skip("Skipping test as symlink replacements don't work on non-linux environment...")
+ }
+
+ watchDir, watchFile := newSymlinkedWatchFile(t)
+
+ w := NewWatcher()
+ require.NoError(t, w.Add(watchFile))
+ events := w.Events(watchFile)
+
+ wg := sync.WaitGroup{}
+ wg.Add(1)
+ go func() {
+ <-events
+ wg.Done()
+ }()
+
+ // Link to another `test.conf` file
+ dataDir2 := path.Join(watchDir, "data2")
+ err := os.Mkdir(dataDir2, 0o777)
+ require.NoError(t, err)
+
+ watchFile2 := path.Join(dataDir2, "test.conf")
+ err = os.WriteFile(watchFile2, []byte("foo: baz\n"), 0o600)
+ require.NoError(t, err)
+
+ // change the symlink using the `ln -sfn` command
+ err = exec.Command("ln", "-sfn", dataDir2, path.Join(watchDir, "data")).Run()
+ require.NoError(t, err)
+
+ // Wait its event to be received.
+ wg.Wait()
+
+ _ = w.Close()
+ })
+
+ t.Run("file added later", func(t *testing.T) {
+ // Given a file being watched
+ watchFile := newWatchFileThatDoesNotExist(t)
+
+ w := NewWatcher()
+ require.NoError(t, w.Add(watchFile))
+ events := w.Events(watchFile)
+
+ wg := sync.WaitGroup{}
+ wg.Add(1)
+ go func() {
+ <-events
+ wg.Done()
+ }()
+
+ // Overwriting the file and waiting its event to be received.
+ err := os.WriteFile(watchFile, []byte("foo: baz\n"), 0o600)
+ require.NoError(t, err)
+ wg.Wait()
+
+ _ = w.Close()
+ })
+}
+
+func TestWatchDir(t *testing.T) {
+ // Given a file being watched
+ watchFile := newWatchFile(t)
+ _, err := os.Stat(watchFile)
+ require.NoError(t, err)
+
+ w := NewWatcher()
+ defer func() {
+ _ = w.Close()
+ }()
+ d := path.Dir(watchFile)
+ require.NoError(t, w.Add(d))
+
+ timeout := time.After(5 * time.Second)
+
+ wg := sync.WaitGroup{}
+ var timeoutErr error
+ wg.Add(1)
+ go func() {
+ select {
+ case <-w.Events(d):
+
+ case <-w.Events(watchFile):
+
+ case <-timeout:
+ timeoutErr = errors.New("timeout")
+ }
+ wg.Done()
+ }()
+
+ // Overwriting the file and waiting its event to be received.
+ err = os.WriteFile(watchFile, []byte("foo: baz\n"), 0o600)
+ require.NoError(t, err)
+ wg.Wait()
+
+ require.NoErrorf(t, timeoutErr, "timeout waiting for event")
+}
+
+func TestWatcherLifecycle(t *testing.T) {
+ watchFile1, watchFile2 := newTwoWatchFile(t)
+
+ w := NewWatcher()
+
+ // Validate Add behavior
+ err := w.Add(watchFile1)
+ require.NoError(t, err)
+ err = w.Add(watchFile2)
+ require.NoError(t, err)
+
+ // Validate events and errors channel are fulfilled.
+ events1 := w.Events(watchFile1)
+ require.NotNil(t, events1)
+ events2 := w.Events(watchFile2)
+ require.NotNil(t, events2)
+
+ errors1 := w.Errors(watchFile1)
+ require.NotNil(t, errors1)
+ errors2 := w.Errors(watchFile2)
+ require.NotNil(t, errors2)
+
+ // Validate Remove behavior
+ err = w.Remove(watchFile1)
+ require.NoError(t, err)
+ events1 = w.Events(watchFile1)
+ require.Nil(t, events1)
+ errors1 = w.Errors(watchFile1)
+ require.Nil(t, errors1)
+ events2 = w.Events(watchFile2)
+ require.NotNil(t, events2)
+ errors2 = w.Errors(watchFile2)
+ require.NotNil(t, errors2)
+
+ fmt.Printf("2\n")
+ // Validate Close behavior
+ err = w.Close()
+ require.NoError(t, err)
+ events1 = w.Events(watchFile1)
+ require.Nil(t, events1)
+ errors1 = w.Errors(watchFile1)
+ require.Nil(t, errors1)
+ events2 = w.Events(watchFile2)
+ require.Nil(t, events2)
+ errors2 = w.Errors(watchFile2)
+ require.Nil(t, errors2)
+}
+
+func TestErrors(t *testing.T) {
+ w := NewWatcher()
+
+ if ch := w.Errors("XYZ"); ch != nil {
+ t.Error("Expected no channel")
+ }
+
+ if ch := w.Events("XYZ"); ch != nil {
+ t.Error("Expected no channel")
+ }
+
+ name := newWatchFile(t)
+ _ = w.Add(name)
+ _ = w.Remove(name)
+
+ if ch := w.Errors("XYZ"); ch != nil {
+ t.Error("Expected no channel")
+ }
+
+ if ch := w.Events(name); ch != nil {
+ t.Error("Expected no channel")
+ }
+
+ _ = w.Close()
+
+ if err := w.Add(name); err == nil {
+ t.Error("Expecting error")
+ }
+
+ if err := w.Remove(name); err == nil {
+ t.Error("Expecting error")
+ }
+
+ if ch := w.Errors(name); ch != nil {
+ t.Error("Expecting nil")
+ }
+
+ if ch := w.Events(name); ch != nil {
+ t.Error("Expecting nil")
+ }
+}
+
+func TestBadWatcher(t *testing.T) {
+ w := NewWatcher()
+ w.(*fileWatcher).funcs.newWatcher = func() (*fsnotify.Watcher, error) {
+ return nil, errors.New("FOOBAR")
+ }
+
+ name := newWatchFile(t)
+ if err := w.Add(name); err == nil {
+ t.Errorf("Expecting error, got nil")
+ }
+ if err := w.Close(); err != nil {
+ t.Errorf("Expecting nil, got %v", err)
+ }
+}
+
+func TestBadAddWatcher(t *testing.T) {
+ w := NewWatcher()
+ w.(*fileWatcher).funcs.addWatcherPath = func(*fsnotify.Watcher, string) error {
+ return errors.New("FOOBAR")
+ }
+
+ name := newWatchFile(t)
+ if err := w.Add(name); err == nil {
+ t.Errorf("Expecting error, got nil")
+ }
+ if err := w.Close(); err != nil {
+ t.Errorf("Expecting nil, got %v", err)
+ }
+}
+
+func TestDuplicateAdd(t *testing.T) {
+ w := NewWatcher()
+ name := newWatchFile(t)
+ defer func() {
+ _ = w.Close()
+ _ = os.Remove(name)
+ }()
+
+ require.NoError(t, w.Add(name))
+ require.Error(t, w.Add(name))
+}
+
+func TestBogusRemove(t *testing.T) {
+ w := NewWatcher()
+ name := newWatchFile(t)
+ defer func() {
+ _ = w.Close()
+ _ = os.Remove(name)
+ }()
+
+ require.Error(t, w.Remove(name))
+}
diff --git a/internal/filewatcher/worker.go b/internal/filewatcher/worker.go
new file mode 100644
index 00000000000..e5ed5e283f4
--- /dev/null
+++ b/internal/filewatcher/worker.go
@@ -0,0 +1,263 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package filewatcher
+
+import (
+ "bufio"
+ "bytes"
+ "crypto/sha256"
+ "fmt"
+ "io"
+ "os"
+ "sync"
+
+ "github.com/fsnotify/fsnotify"
+)
+
+type worker struct {
+ mu sync.RWMutex
+
+ // watcher is a fsnotify watcher that watches the parent
+ // dir of watchedFiles.
+ dirWatcher *fsnotify.Watcher
+
+ // The worker maintains a map of channels keyed by watched file path.
+ // The worker watches parent path of given path,
+ // and filters out events of given path, then redirect
+ // to the result channel.
+ // Note that for symlink files, the content in received events
+ // do not have to be related to the file itself.
+ watchedFiles map[string]*fileTracker
+
+ // tracker lifecycle
+ retireTrackerCh chan *fileTracker
+
+ // tells the worker to exit
+ terminateCh chan bool
+}
+
+type fileTracker struct {
+ events chan fsnotify.Event
+ errors chan error
+
+ // Hash sum to indicate if a file has been updated.
+ hash []byte
+}
+
+func newWorker(path string, funcs *patchTable) (*worker, error) {
+ dirWatcher, err := funcs.newWatcher()
+ if err != nil {
+ return nil, err
+ }
+
+ if err = funcs.addWatcherPath(dirWatcher, path); err != nil {
+ _ = dirWatcher.Close()
+ return nil, err
+ }
+
+ wk := &worker{
+ dirWatcher: dirWatcher,
+ watchedFiles: make(map[string]*fileTracker),
+ retireTrackerCh: make(chan *fileTracker),
+ terminateCh: make(chan bool),
+ }
+
+ go wk.listen()
+
+ return wk, nil
+}
+
+func (wk *worker) listen() {
+ wk.loop()
+
+ _ = wk.dirWatcher.Close()
+
+ // drain any retiring trackers that may be pending
+ wk.drainRetiringTrackers()
+
+ // clean up the rest
+ for _, ft := range wk.watchedFiles {
+ retireTracker(ft)
+ }
+}
+
+func (wk *worker) loop() {
+ for {
+ select {
+ case event := <-wk.dirWatcher.Events:
+ // work on a copy of the watchedFiles map, so that we don't interfere
+ // with the caller's use of the map
+ for path, ft := range wk.getTrackers() {
+ if ft.events == nil {
+ // tracker has been retired, skip it
+ continue
+ }
+
+ sum, isDir := getHashSum(path)
+ if isDir || !bytes.Equal(sum, ft.hash) {
+ ft.hash = sum
+ select {
+ case ft.events <- event:
+ // nothing to do
+
+ case ft := <-wk.retireTrackerCh:
+ retireTracker(ft)
+
+ case <-wk.terminateCh:
+ return
+ }
+ }
+ }
+
+ case err := <-wk.dirWatcher.Errors:
+ for _, ft := range wk.getTrackers() {
+ if ft.errors == nil {
+ // tracker has been retired, skip it
+ continue
+ }
+
+ select {
+ case ft.errors <- err:
+ // nothing to do
+
+ case ft := <-wk.retireTrackerCh:
+ retireTracker(ft)
+
+ case <-wk.terminateCh:
+ return
+ }
+ }
+
+ case ft := <-wk.retireTrackerCh:
+ retireTracker(ft)
+
+ case <-wk.terminateCh:
+ return
+ }
+ }
+}
+
+// drainRetiringTrackers used only by the worker goroutine
+func (wk *worker) drainRetiringTrackers() {
+ // cleanup any trackers that were in the process
+ // of being retired, but didn't get processed due
+ // to termination
+ for {
+ select {
+ case ft := <-wk.retireTrackerCh:
+ retireTracker(ft)
+ default:
+ return
+ }
+ }
+}
+
+// getTrackers make a local copy of the set of trackers to avoid contention with callers
+// used only by the worker goroutine
+func (wk *worker) getTrackers() map[string]*fileTracker {
+ wk.mu.RLock()
+
+ result := make(map[string]*fileTracker, len(wk.watchedFiles))
+ for k, v := range wk.watchedFiles {
+ result[k] = v
+ }
+
+ wk.mu.RUnlock()
+ return result
+}
+
+// used only by the worker goroutine
+func retireTracker(ft *fileTracker) {
+ close(ft.events)
+ close(ft.errors)
+ ft.events = nil
+ ft.errors = nil
+}
+
+func (wk *worker) terminate() {
+ wk.terminateCh <- true
+}
+
+func (wk *worker) addPath(path string) error {
+ wk.mu.Lock()
+ defer wk.mu.Unlock()
+
+ ft := wk.watchedFiles[path]
+ if ft != nil {
+ return fmt.Errorf("path %s is already being watched", path)
+ }
+
+ h, _ := getHashSum(path)
+ ft = &fileTracker{
+ events: make(chan fsnotify.Event),
+ errors: make(chan error),
+ hash: h,
+ }
+ wk.watchedFiles[path] = ft
+
+ return nil
+}
+
+func (wk *worker) removePath(path string) error {
+ wk.mu.Lock()
+ defer wk.mu.Unlock()
+
+ ft := wk.watchedFiles[path]
+ if ft == nil {
+ return fmt.Errorf("path %s not found", path)
+ }
+
+ delete(wk.watchedFiles, path)
+
+ wk.retireTrackerCh <- ft
+ return nil
+}
+
+func (wk *worker) eventChannel(path string) chan fsnotify.Event {
+ wk.mu.RLock()
+ defer wk.mu.RUnlock()
+
+ if ft := wk.watchedFiles[path]; ft != nil {
+ return ft.events
+ }
+
+ return nil
+}
+
+func (wk *worker) errorChannel(path string) chan error {
+ wk.mu.RLock()
+ defer wk.mu.RUnlock()
+
+ if ft := wk.watchedFiles[path]; ft != nil {
+ return ft.errors
+ }
+
+ return nil
+}
+
+// getHashSum return the hash of the given file, or nil if there's a problem, or it's a directory.
+func getHashSum(file string) ([]byte, bool) {
+ f, err := os.Open(file)
+ if err != nil {
+ return nil, false
+ }
+ defer func() {
+ _ = f.Close()
+ }()
+
+ fi, err := f.Stat()
+ if err != nil {
+ return nil, false
+ }
+ if fi.IsDir() {
+ return nil, true
+ }
+
+ r := bufio.NewReader(f)
+ h := sha256.New()
+ _, _ = io.Copy(h, r)
+ return h.Sum(nil), false
+}
diff --git a/internal/gatewayapi/address.go b/internal/gatewayapi/address.go
index fea4aeae7db..40b5106f42c 100644
--- a/internal/gatewayapi/address.go
+++ b/internal/gatewayapi/address.go
@@ -7,15 +7,17 @@ package gatewayapi
import (
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
)
var _ AddressesTranslator = (*Translator)(nil)
type AddressesTranslator interface {
- ProcessAddresses(gateways []*GatewayContext, xdsIR XdsIRMap, infraIR InfraIRMap, resources *Resources)
+ ProcessAddresses(gateways []*GatewayContext, xdsIR resource.XdsIRMap, infraIR resource.InfraIRMap)
}
-func (t *Translator) ProcessAddresses(gateways []*GatewayContext, xdsIR XdsIRMap, infraIR InfraIRMap, resources *Resources) {
+func (t *Translator) ProcessAddresses(gateways []*GatewayContext, xdsIR resource.XdsIRMap, infraIR resource.InfraIRMap) {
for _, gateway := range gateways {
// Infra IR already exist
irKey := t.getIRKey(gateway.Gateway)
diff --git a/internal/gatewayapi/backend.go b/internal/gatewayapi/backend.go
index 8c9f20f69d5..6b9bb095714 100644
--- a/internal/gatewayapi/backend.go
+++ b/internal/gatewayapi/backend.go
@@ -58,13 +58,8 @@ func validateBackend(backend *egv1a1.Backend) error {
ip, err := netip.ParseAddr(ep.IP.Address)
if err != nil {
return fmt.Errorf("IP address %s is invalid", ep.IP.Address)
- } else {
- if !ip.Is4() {
- return fmt.Errorf("IP address %s is not IPv4", ep.IP.Address)
- }
- if ip.IsLoopback() {
- return fmt.Errorf("IP address %s in the loopback range is not supported", ep.IP.Address)
- }
+ } else if ip.IsLoopback() {
+ return fmt.Errorf("IP address %s in the loopback range is not supported", ep.IP.Address)
}
}
}
diff --git a/internal/gatewayapi/backendtlspolicy.go b/internal/gatewayapi/backendtlspolicy.go
index 28f77bf825b..0f99145f5a9 100644
--- a/internal/gatewayapi/backendtlspolicy.go
+++ b/internal/gatewayapi/backendtlspolicy.go
@@ -7,19 +7,25 @@ package gatewayapi
import (
"fmt"
+ "reflect"
+ "k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
)
-func (t *Translator) applyBackendTLSSetting(backendRef gwapiv1.BackendObjectReference, backendNamespace string, parent gwapiv1a2.ParentReference, resources *Resources, envoyProxy *egv1a1.EnvoyProxy) *ir.TLSUpstreamConfig {
- upstreamConfig, policy := t.processBackendTLSPolicy(backendRef, backendNamespace, parent, resources, envoyProxy)
+func (t *Translator) applyBackendTLSSetting(backendRef gwapiv1.BackendObjectReference, backendNamespace string, parent gwapiv1a2.ParentReference, resources *resource.Resources, envoyProxy *egv1a1.EnvoyProxy) (*ir.TLSUpstreamConfig, error) {
+ upstreamConfig, policy, err := t.processBackendTLSPolicy(backendRef, backendNamespace, parent, resources)
+ if err != nil {
+ return nil, err
+ }
return t.applyEnvoyProxyBackendTLSSetting(policy, upstreamConfig, resources, parent, envoyProxy)
}
@@ -27,19 +33,14 @@ func (t *Translator) processBackendTLSPolicy(
backendRef gwapiv1.BackendObjectReference,
backendNamespace string,
parent gwapiv1a2.ParentReference,
- resources *Resources,
- envoyProxy *egv1a1.EnvoyProxy,
-) (*ir.TLSUpstreamConfig, *gwapiv1a3.BackendTLSPolicy) {
- policy := getBackendTLSPolicy(resources.BackendTLSPolicies, backendRef, backendNamespace)
+ resources *resource.Resources,
+) (*ir.TLSUpstreamConfig, *gwapiv1a3.BackendTLSPolicy, error) {
+ policy := getBackendTLSPolicy(resources.BackendTLSPolicies, backendRef, backendNamespace, resources)
if policy == nil {
- return nil, nil
+ return nil, nil, nil
}
tlsBundle, err := getBackendTLSBundle(policy, resources)
- if err == nil && tlsBundle == nil {
- return nil, nil
- }
-
ancestorRefs := getAncestorRefs(policy)
ancestorRefs = append(ancestorRefs, parent)
@@ -50,42 +51,16 @@ func (t *Translator) processBackendTLSPolicy(
policy.Generation,
status.Error2ConditionMsg(err),
)
- return nil, nil
+ return nil, nil, err
}
status.SetAcceptedForPolicyAncestors(&policy.Status, ancestorRefs, t.GatewayControllerName)
- // apply defaults as per envoyproxy
- if envoyProxy != nil {
- if envoyProxy.Spec.BackendTLS != nil {
- if len(envoyProxy.Spec.BackendTLS.Ciphers) > 0 {
- tlsBundle.Ciphers = envoyProxy.Spec.BackendTLS.Ciphers
- }
- if len(envoyProxy.Spec.BackendTLS.ECDHCurves) > 0 {
- tlsBundle.ECDHCurves = envoyProxy.Spec.BackendTLS.ECDHCurves
- }
- if len(envoyProxy.Spec.BackendTLS.SignatureAlgorithms) > 0 {
- tlsBundle.SignatureAlgorithms = envoyProxy.Spec.BackendTLS.SignatureAlgorithms
- }
- if envoyProxy.Spec.BackendTLS.MinVersion != nil {
- tlsBundle.MinVersion = ptr.To(ir.TLSVersion(*envoyProxy.Spec.BackendTLS.MinVersion))
- }
- if envoyProxy.Spec.BackendTLS.MaxVersion != nil {
- tlsBundle.MaxVersion = ptr.To(ir.TLSVersion(*envoyProxy.Spec.BackendTLS.MaxVersion))
- }
- if len(envoyProxy.Spec.BackendTLS.ALPNProtocols) > 0 {
- tlsBundle.ALPNProtocols = make([]string, len(envoyProxy.Spec.BackendTLS.ALPNProtocols))
- for i := range envoyProxy.Spec.BackendTLS.ALPNProtocols {
- tlsBundle.ALPNProtocols[i] = string(envoyProxy.Spec.BackendTLS.ALPNProtocols[i])
- }
- }
- }
- }
- return tlsBundle, policy
+ return tlsBundle, policy, nil
}
-func (t *Translator) applyEnvoyProxyBackendTLSSetting(policy *gwapiv1a3.BackendTLSPolicy, tlsConfig *ir.TLSUpstreamConfig, resources *Resources, parent gwapiv1a2.ParentReference, ep *egv1a1.EnvoyProxy) *ir.TLSUpstreamConfig {
+func (t *Translator) applyEnvoyProxyBackendTLSSetting(policy *gwapiv1a3.BackendTLSPolicy, tlsConfig *ir.TLSUpstreamConfig, resources *resource.Resources, parent gwapiv1a2.ParentReference, ep *egv1a1.EnvoyProxy) (*ir.TLSUpstreamConfig, error) {
if ep == nil || ep.Spec.BackendTLS == nil || tlsConfig == nil {
- return tlsConfig
+ return tlsConfig, nil
}
if len(ep.Spec.BackendTLS.Ciphers) > 0 {
@@ -114,28 +89,41 @@ func (t *Translator) applyEnvoyProxyBackendTLSSetting(policy *gwapiv1a3.BackendT
ancestorRefs := []gwapiv1a2.ParentReference{
parent,
}
+ var err error
if ns != ep.Namespace {
+ err = fmt.Errorf("ClientCertificateRef Secret is not located in the same namespace as Envoyproxy. Secret namespace: %s does not match Envoyproxy namespace: %s", ns, ep.Namespace)
status.SetTranslationErrorForPolicyAncestors(&policy.Status,
ancestorRefs,
t.GatewayControllerName,
policy.Generation,
- status.Error2ConditionMsg(fmt.Errorf("client authentication TLS secret is not located in the same namespace as Envoyproxy. Secret namespace: %s does not match Envoyproxy namespace: %s", ns, ep.Namespace)))
- return tlsConfig
+ status.Error2ConditionMsg(err))
+ return tlsConfig, err
}
secret := resources.GetSecret(ns, string(ep.Spec.BackendTLS.ClientCertificateRef.Name))
if secret == nil {
+ err = fmt.Errorf(
+ "failed to locate TLS secret for client auth: %s specified in EnvoyProxy %s",
+ types.NamespacedName{
+ Namespace: ep.Namespace,
+ Name: string(ep.Spec.BackendTLS.ClientCertificateRef.Name),
+ }.String(),
+ types.NamespacedName{
+ Namespace: ep.Namespace,
+ Name: ep.Name,
+ }.String(),
+ )
status.SetTranslationErrorForPolicyAncestors(&policy.Status,
ancestorRefs,
t.GatewayControllerName,
policy.Generation,
- status.Error2ConditionMsg(fmt.Errorf("failed to locate TLS secret for client auth: %s in namespace: %s", ep.Spec.BackendTLS.ClientCertificateRef.Name, ns)),
+ status.Error2ConditionMsg(err),
)
- return tlsConfig
+ return tlsConfig, err
}
tlsConf := irTLSConfigs(secret)
tlsConfig.ClientCertificates = tlsConf.Certificates
}
- return tlsConfig
+ return tlsConfig, nil
}
func backendTLSTargetMatched(policy gwapiv1a3.BackendTLSPolicy, target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName, backendNamespace string) bool {
@@ -144,17 +132,25 @@ func backendTLSTargetMatched(policy gwapiv1a3.BackendTLSPolicy, target gwapiv1a2
target.Kind == currTarget.Kind &&
backendNamespace == policy.Namespace &&
target.Name == currTarget.Name {
- if currTarget.SectionName != nil && *currTarget.SectionName != *target.SectionName {
- return false
+ // if section name is not set, then it targets the entire backend
+ if currTarget.SectionName == nil {
+ return true
+ } else if reflect.DeepEqual(currTarget.SectionName, target.SectionName) {
+ return true
}
- return true
}
}
return false
}
-func getBackendTLSPolicy(policies []*gwapiv1a3.BackendTLSPolicy, backendRef gwapiv1a2.BackendObjectReference, backendNamespace string) *gwapiv1a3.BackendTLSPolicy {
- target := getTargetBackendReference(backendRef)
+func getBackendTLSPolicy(
+ policies []*gwapiv1a3.BackendTLSPolicy,
+ backendRef gwapiv1a2.BackendObjectReference,
+ backendNamespace string,
+ resources *resource.Resources,
+) *gwapiv1a3.BackendTLSPolicy {
+ // SectionName is port number for EG Backend object
+ target := getTargetBackendReference(backendRef, backendNamespace, resources)
for _, policy := range policies {
if backendTLSTargetMatched(*policy, target, backendNamespace) {
return policy
@@ -163,7 +159,7 @@ func getBackendTLSPolicy(policies []*gwapiv1a3.BackendTLSPolicy, backendRef gwap
return nil
}
-func getBackendTLSBundle(backendTLSPolicy *gwapiv1a3.BackendTLSPolicy, resources *Resources) (*ir.TLSUpstreamConfig, error) {
+func getBackendTLSBundle(backendTLSPolicy *gwapiv1a3.BackendTLSPolicy, resources *resource.Resources) (*ir.TLSUpstreamConfig, error) {
tlsBundle := &ir.TLSUpstreamConfig{
SNI: string(backendTLSPolicy.Spec.Validation.Hostname),
UseSystemTrustStore: ptr.Deref(backendTLSPolicy.Spec.Validation.WellKnownCACertificates, "") == gwapiv1a3.WellKnownCACertificatesSystem,
@@ -177,7 +173,7 @@ func getBackendTLSBundle(backendTLSPolicy *gwapiv1a3.BackendTLSPolicy, resources
kind := string(caRef.Kind)
switch kind {
- case KindConfigMap:
+ case resource.KindConfigMap:
for _, cmap := range resources.ConfigMaps {
if cmap.Name == string(caRef.Name) {
if crt, dataOk := cmap.Data["ca.crt"]; dataOk {
@@ -190,7 +186,7 @@ func getBackendTLSBundle(backendTLSPolicy *gwapiv1a3.BackendTLSPolicy, resources
}
}
}
- case KindSecret:
+ case resource.KindSecret:
for _, secret := range resources.Secrets {
if secret.Name == string(caRef.Name) {
if crt, dataOk := secret.Data["ca.crt"]; dataOk {
diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go
index 41cb02ce112..0934629428b 100644
--- a/internal/gatewayapi/backendtrafficpolicy.go
+++ b/internal/gatewayapi/backendtrafficpolicy.go
@@ -9,10 +9,9 @@ import (
"errors"
"fmt"
"math"
- "math/big"
"sort"
+ "strconv"
"strings"
- "time"
perr "github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -22,9 +21,11 @@ import (
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils"
+ "github.com/envoyproxy/gateway/internal/utils/ratelimit"
"github.com/envoyproxy/gateway/internal/utils/regex"
)
@@ -32,13 +33,14 @@ const (
MaxConsistentHashTableSize = 5000011 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-maglevlbconfig
)
-func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv1a1.BackendTrafficPolicy,
+func (t *Translator) ProcessBackendTrafficPolicies(resources *resource.Resources,
gateways []*GatewayContext,
routes []RouteContext,
- xdsIR XdsIRMap,
+ xdsIR resource.XdsIRMap,
) []*egv1a1.BackendTrafficPolicy {
res := []*egv1a1.BackendTrafficPolicy{}
+ backendTrafficPolicies := resources.BackendTrafficPolicies
// Sort based on timestamp
sort.Slice(backendTrafficPolicies, func(i, j int) bool {
return backendTrafficPolicies[i].CreationTimestamp.Before(&(backendTrafficPolicies[j].CreationTimestamp))
@@ -75,7 +77,7 @@ func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv
policyName := utils.NamespacedName(currPolicy)
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes)
for _, currTarget := range targetRefs {
- if currTarget.Kind != KindGateway {
+ if currTarget.Kind != resource.KindGateway {
policy, found := handledPolicies[policyName]
if !found {
policy = currPolicy.DeepCopy()
@@ -95,7 +97,7 @@ func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv
parentRefs := GetParentReferences(route)
ancestorRefs := make([]gwapiv1a2.ParentReference, 0, len(parentRefs))
for _, p := range parentRefs {
- if p.Kind == nil || *p.Kind == KindGateway {
+ if p.Kind == nil || *p.Kind == resource.KindGateway {
namespace := route.GetNamespace()
if p.Namespace != nil {
namespace = string(*p.Namespace)
@@ -129,7 +131,7 @@ func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv
}
// Set conditions for translation error if it got any
- if err := t.translateBackendTrafficPolicyForRoute(policy, route, xdsIR); err != nil {
+ if err := t.translateBackendTrafficPolicyForRoute(policy, route, xdsIR, resources); err != nil {
status.SetTranslationErrorForPolicyAncestors(&policy.Status,
ancestorRefs,
t.GatewayControllerName,
@@ -149,7 +151,7 @@ func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv
policyName := utils.NamespacedName(currPolicy)
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways)
for _, currTarget := range targetRefs {
- if currTarget.Kind == KindGateway {
+ if currTarget.Kind == resource.KindGateway {
policy, found := handledPolicies[policyName]
if !found {
policy = currPolicy.DeepCopy()
@@ -183,7 +185,7 @@ func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv
}
// Set conditions for translation error if it got any
- if err := t.translateBackendTrafficPolicyForGateway(policy, currTarget, gateway, xdsIR); err != nil {
+ if err := t.translateBackendTrafficPolicyForGateway(policy, currTarget, gateway, xdsIR, resources); err != nil {
status.SetTranslationErrorForPolicyAncestors(&policy.Status,
ancestorRefs,
t.GatewayControllerName,
@@ -221,11 +223,10 @@ func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv
}
func resolveBTPolicyGatewayTargetRef(policy *egv1a1.BackendTrafficPolicy, target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName, gateways map[types.NamespacedName]*policyGatewayTargetContext) (*GatewayContext, *status.PolicyResolveError) {
- targetNs := policy.Namespace
// Check if the gateway exists
key := types.NamespacedName{
Name: string(target.Name),
- Namespace: targetNs,
+ Namespace: policy.Namespace,
}
gateway, ok := gateways[key]
@@ -234,17 +235,6 @@ func resolveBTPolicyGatewayTargetRef(policy *egv1a1.BackendTrafficPolicy, target
return nil, nil
}
- // Ensure Policy and target are in the same namespace
- if policy.Namespace != targetNs {
- message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, BackendTrafficPolicy can only target a resource in the same namespace.",
- policy.Namespace, targetNs)
-
- return gateway.GatewayContext, &status.PolicyResolveError{
- Reason: gwapiv1a2.PolicyReasonInvalid,
- Message: message,
- }
- }
-
// Check if another policy targeting the same Gateway exists
if gateway.attached {
message := fmt.Sprintf("Unable to target Gateway %s, another BackendTrafficPolicy has already attached to it",
@@ -264,13 +254,11 @@ func resolveBTPolicyGatewayTargetRef(policy *egv1a1.BackendTrafficPolicy, target
}
func resolveBTPolicyRouteTargetRef(policy *egv1a1.BackendTrafficPolicy, target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName, routes map[policyTargetRouteKey]*policyRouteTargetContext) (RouteContext, *status.PolicyResolveError) {
- targetNs := policy.Namespace
-
// Check if the route exists
key := policyTargetRouteKey{
Kind: string(target.Kind),
Name: string(target.Name),
- Namespace: targetNs,
+ Namespace: policy.Namespace,
}
route, ok := routes[key]
@@ -279,17 +267,6 @@ func resolveBTPolicyRouteTargetRef(policy *egv1a1.BackendTrafficPolicy, target g
return nil, nil
}
- // Ensure Policy and target are in the same namespace
- if policy.Namespace != targetNs {
- message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, BackendTrafficPolicy can only target a resource in the same namespace.",
- policy.Namespace, targetNs)
-
- return route.RouteContext, &status.PolicyResolveError{
- Reason: gwapiv1a2.PolicyReasonInvalid,
- Message: message,
- }
- }
-
// Check if another policy targeting the same xRoute exists
if route.attached {
message := fmt.Sprintf("Unable to target %s %s, another BackendTrafficPolicy has already attached to it",
@@ -308,7 +285,12 @@ func resolveBTPolicyRouteTargetRef(policy *egv1a1.BackendTrafficPolicy, target g
return route.RouteContext, nil
}
-func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.BackendTrafficPolicy, route RouteContext, xdsIR XdsIRMap) error {
+func (t *Translator) translateBackendTrafficPolicyForRoute(
+ policy *egv1a1.BackendTrafficPolicy,
+ route RouteContext,
+ xdsIR resource.XdsIRMap,
+ resources *resource.Resources,
+) error {
var (
rl *ir.RateLimit
lb *ir.LoadBalancer
@@ -320,6 +302,9 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
ka *ir.TCPKeepalive
rt *ir.Retry
bc *ir.BackendConnection
+ ds *ir.DNS
+ h2 *ir.HTTP2Settings
+ ro *ir.ResponseOverride
err, errs error
)
@@ -330,55 +315,48 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
errs = errors.Join(errs, err)
}
}
- if policy.Spec.LoadBalancer != nil {
- if lb, err = t.buildLoadBalancer(policy); err != nil {
- err = perr.WithMessage(err, "LoadBalancer")
- errs = errors.Join(errs, err)
- }
+ if lb, err = buildLoadBalancer(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "LoadBalancer")
+ errs = errors.Join(errs, err)
}
- if policy.Spec.ProxyProtocol != nil {
- pp = t.buildProxyProtocol(policy)
- }
- if policy.Spec.HealthCheck != nil {
- hc = t.buildHealthCheck(policy)
- }
- if policy.Spec.CircuitBreaker != nil {
- if cb, err = t.buildCircuitBreaker(policy); err != nil {
- err = perr.WithMessage(err, "CircuitBreaker")
- errs = errors.Join(errs, err)
- }
+ pp = buildProxyProtocol(policy.Spec.ClusterSettings)
+ hc = buildHealthCheck(policy.Spec.ClusterSettings)
+ if cb, err = buildCircuitBreaker(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "CircuitBreaker")
+ errs = errors.Join(errs, err)
}
if policy.Spec.FaultInjection != nil {
fi = t.buildFaultInjection(policy)
}
- if policy.Spec.TCPKeepalive != nil {
- if ka, err = t.buildTCPKeepAlive(policy); err != nil {
- err = perr.WithMessage(err, "TCPKeepalive")
- errs = errors.Join(errs, err)
- }
+ if ka, err = buildTCPKeepAlive(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "TCPKeepalive")
+ errs = errors.Join(errs, err)
}
if policy.Spec.Retry != nil {
- rt = t.buildRetry(policy)
+ rt = buildRetry(policy.Spec.Retry)
}
- if policy.Spec.Timeout != nil {
- if to, err = t.buildTimeout(policy, nil); err != nil {
- err = perr.WithMessage(err, "Timeout")
- errs = errors.Join(errs, err)
- }
+ if to, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "Timeout")
+ errs = errors.Join(errs, err)
}
- if policy.Spec.Connection != nil {
- if bc, err = t.buildBackendConnection(policy); err != nil {
- err = perr.WithMessage(err, "BackendConnection")
- errs = errors.Join(errs, err)
- }
+ if bc, err = buildBackendConnection(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "BackendConnection")
+ errs = errors.Join(errs, err)
+ }
+
+ if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil {
+ err = perr.WithMessage(err, "HTTP2")
+ errs = errors.Join(errs, err)
}
- // Early return if got any errors
- if errs != nil {
- return errs
+ if ro, err = buildResponseOverride(policy, resources); err != nil {
+ err = perr.WithMessage(err, "ResponseOverride")
+ errs = errors.Join(errs, err)
}
+ ds = translateDNS(policy.Spec.ClusterSettings)
+
// Apply IR to all relevant routes
prefix := irRoutePrefix(route)
@@ -393,6 +371,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
r.TCPKeepalive = ka
r.Timeout = to
r.BackendConnection = bc
+ r.DNS = ds
}
}
}
@@ -403,8 +382,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
if strings.HasPrefix(r.Destination.Name, prefix) {
r.LoadBalancer = lb
- r.Timeout = to
- r.BackendConnection = bc
+ r.DNS = ds
}
}
}
@@ -413,6 +391,18 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
for _, r := range http.Routes {
// Apply if there is a match
if strings.HasPrefix(r.Name, prefix) {
+ if errs != nil {
+ // Return a 500 direct response
+ r.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
+ }
+ continue
+ }
+
+ if localTo, err := buildClusterSettingsTimeout(policy.Spec.ClusterSettings); err == nil {
+ to = localTo
+ }
+
r.Traffic = &ir.TrafficFeatures{
RateLimit: rl,
LoadBalancer: lb,
@@ -423,18 +413,15 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
TCPKeepalive: ka,
Retry: rt,
BackendConnection: bc,
+ HTTP2: h2,
+ DNS: ds,
+ Timeout: to,
+ ResponseOverride: ro,
}
// Update the Host field in HealthCheck, now that we have access to the Route Hostname.
r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname)
- // Some timeout setting originate from the route.
- if policy.Spec.Timeout != nil {
- if to, err = t.buildTimeout(policy, r); err == nil {
- r.Traffic.Timeout = to
- }
- }
-
if policy.Spec.UseClientProtocol != nil {
r.UseClientProtocol = policy.Spec.UseClientProtocol
}
@@ -443,10 +430,16 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
}
}
- return nil
+ return errs
}
-func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.BackendTrafficPolicy, target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName, gateway *GatewayContext, xdsIR XdsIRMap) error {
+func (t *Translator) translateBackendTrafficPolicyForGateway(
+ policy *egv1a1.BackendTrafficPolicy,
+ target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName,
+ gateway *GatewayContext,
+ xdsIR resource.XdsIRMap,
+ resources *resource.Resources,
+) error {
var (
rl *ir.RateLimit
lb *ir.LoadBalancer
@@ -457,6 +450,9 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
ct *ir.Timeout
ka *ir.TCPKeepalive
rt *ir.Retry
+ ds *ir.DNS
+ h2 *ir.HTTP2Settings
+ ro *ir.ResponseOverride
err, errs error
)
@@ -467,48 +463,41 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
errs = errors.Join(errs, err)
}
}
- if policy.Spec.LoadBalancer != nil {
- if lb, err = t.buildLoadBalancer(policy); err != nil {
- err = perr.WithMessage(err, "LoadBalancer")
- errs = errors.Join(errs, err)
- }
- }
- if policy.Spec.ProxyProtocol != nil {
- pp = t.buildProxyProtocol(policy)
+ if lb, err = buildLoadBalancer(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "LoadBalancer")
+ errs = errors.Join(errs, err)
}
- if policy.Spec.HealthCheck != nil {
- hc = t.buildHealthCheck(policy)
- }
- if policy.Spec.CircuitBreaker != nil {
- if cb, err = t.buildCircuitBreaker(policy); err != nil {
- err = perr.WithMessage(err, "CircuitBreaker")
- errs = errors.Join(errs, err)
- }
+ pp = buildProxyProtocol(policy.Spec.ClusterSettings)
+ hc = buildHealthCheck(policy.Spec.ClusterSettings)
+ if cb, err = buildCircuitBreaker(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "CircuitBreaker")
+ errs = errors.Join(errs, err)
}
if policy.Spec.FaultInjection != nil {
fi = t.buildFaultInjection(policy)
}
- if policy.Spec.TCPKeepalive != nil {
- if ka, err = t.buildTCPKeepAlive(policy); err != nil {
- err = perr.WithMessage(err, "TCPKeepalive")
- errs = errors.Join(errs, err)
- }
+ if ka, err = buildTCPKeepAlive(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "TCPKeepalive")
+ errs = errors.Join(errs, err)
}
if policy.Spec.Retry != nil {
- rt = t.buildRetry(policy)
+ rt = buildRetry(policy.Spec.Retry)
}
- if policy.Spec.Timeout != nil {
- if ct, err = t.buildTimeout(policy, nil); err != nil {
- err = perr.WithMessage(err, "Timeout")
- errs = errors.Join(errs, err)
- }
+ if ct, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "Timeout")
+ errs = errors.Join(errs, err)
}
-
- // Early return if got any errors
- if errs != nil {
- return errs
+ if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil {
+ err = perr.WithMessage(err, "HTTP2")
+ errs = errors.Join(errs, err)
+ }
+ if ro, err = buildResponseOverride(policy, resources); err != nil {
+ err = perr.WithMessage(err, "ResponseOverride")
+ errs = errors.Join(errs, err)
}
+ ds = translateDNS(policy.Spec.ClusterSettings)
+
// Apply IR to all the routes within the specific Gateway
// If the feature is already set, then skip it, since it must be have
// set by a policy attaching to the route
@@ -525,22 +514,15 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
}
for _, r := range tcp.Routes {
- // policy(targeting xRoute) has already set it, so we skip it.
- if r.LoadBalancer != nil || r.ProxyProtocol != nil ||
- r.HealthCheck != nil || r.CircuitBreaker != nil ||
- r.TCPKeepalive != nil || r.Timeout != nil {
- continue
- }
-
- r.LoadBalancer = lb
- r.ProxyProtocol = pp
- r.HealthCheck = hc
- r.CircuitBreaker = cb
- r.TCPKeepalive = ka
-
- if r.Timeout == nil {
- r.Timeout = ct
- }
+ // only set attributes which weren't already set by a more
+ // specific policy
+ setIfNil(&r.LoadBalancer, lb)
+ setIfNil(&r.ProxyProtocol, pp)
+ setIfNil(&r.HealthCheck, hc)
+ setIfNil(&r.CircuitBreaker, cb)
+ setIfNil(&r.TCPKeepalive, ka)
+ setIfNil(&r.Timeout, ct)
+ setIfNil(&r.DNS, ds)
}
}
@@ -556,15 +538,10 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
route := udp.Route
- // policy(targeting xRoute) has already set it, so we skip it.
- if route.LoadBalancer != nil || route.Timeout != nil {
- continue
- }
-
- route.LoadBalancer = lb
- if route.Timeout == nil {
- route.Timeout = ct
- }
+ // only set attributes which weren't already set by a more
+ // specific policy
+ setIfNil(&route.LoadBalancer, lb)
+ setIfNil(&route.DNS, ds)
}
for _, http := range x.HTTP {
@@ -582,35 +559,42 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
continue
}
+ if errs != nil {
+ // Return a 500 direct response
+ r.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
+ }
+ continue
+ }
+
r.Traffic = &ir.TrafficFeatures{
- RateLimit: rl,
- LoadBalancer: lb,
- ProxyProtocol: pp,
- HealthCheck: hc,
- CircuitBreaker: cb,
- FaultInjection: fi,
- TCPKeepalive: ka,
- Retry: rt,
+ RateLimit: rl,
+ LoadBalancer: lb,
+ ProxyProtocol: pp,
+ HealthCheck: hc,
+ CircuitBreaker: cb,
+ FaultInjection: fi,
+ TCPKeepalive: ka,
+ Retry: rt,
+ HTTP2: h2,
+ DNS: ds,
+ ResponseOverride: ro,
}
// Update the Host field in HealthCheck, now that we have access to the Route Hostname.
r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname)
- if policy.Spec.Timeout != nil {
- if ct, err = t.buildTimeout(policy, r); err == nil {
- r.Traffic.Timeout = ct
- }
+ if ct, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings); err == nil {
+ r.Traffic.Timeout = ct
}
if policy.Spec.UseClientProtocol != nil {
- if r.UseClientProtocol == nil {
- r.UseClientProtocol = policy.Spec.UseClientProtocol
- }
+ setIfNil(&r.UseClientProtocol, policy.Spec.UseClientProtocol)
}
}
}
- return nil
+ return errs
}
func (t *Translator) buildRateLimit(policy *egv1a1.BackendTrafficPolicy) (*ir.RateLimit, error) {
@@ -636,7 +620,7 @@ func (t *Translator) buildLocalRateLimit(policy *egv1a1.BackendTrafficPolicy) (*
// limit. If no such rule is found, EG uses a default limit of uint32 max.
var defaultLimit *ir.RateLimitValue
for _, rule := range local.Rules {
- if rule.ClientSelectors == nil || len(rule.ClientSelectors) == 0 {
+ if len(rule.ClientSelectors) == 0 {
if defaultLimit != nil {
return nil, fmt.Errorf("local rateLimit can not have more than one rule without clientSelectors")
}
@@ -658,9 +642,9 @@ func (t *Translator) buildLocalRateLimit(policy *egv1a1.BackendTrafficPolicy) (*
// Validate that the rule limit unit is a multiple of the default limit unit.
// This is required by Envoy local rateLimit implementation.
// see https://github.com/envoyproxy/envoy/blob/6d9a6e995f472526de2b75233abca69aa00021ed/source/extensions/filters/common/local_ratelimit/local_ratelimit_impl.cc#L49
- defaultLimitUnit := ratelimitUnitToDuration(egv1a1.RateLimitUnit(defaultLimit.Unit))
+ defaultLimitUnit := ratelimit.UnitToSeconds(egv1a1.RateLimitUnit(defaultLimit.Unit))
for _, rule := range local.Rules {
- ruleLimitUint := ratelimitUnitToDuration(rule.Limit.Unit)
+ ruleLimitUint := ratelimit.UnitToSeconds(rule.Limit.Unit)
if defaultLimitUnit == 0 || ruleLimitUint%defaultLimitUnit != 0 {
return nil, fmt.Errorf("local rateLimit rule limit unit must be a multiple of the default limit unit")
}
@@ -752,8 +736,9 @@ func buildRateLimitRule(rule egv1a1.RateLimitRule) (*ir.RateLimitRule, error) {
fallthrough
case *header.Type == egv1a1.HeaderMatchExact && header.Value != nil:
m := &ir.StringMatch{
- Name: header.Name,
- Exact: header.Value,
+ Name: header.Name,
+ Exact: header.Value,
+ Invert: header.Invert,
}
irRule.HeaderMatches = append(irRule.HeaderMatches, m)
case *header.Type == egv1a1.HeaderMatchRegularExpression && header.Value != nil:
@@ -763,9 +748,14 @@ func buildRateLimitRule(rule egv1a1.RateLimitRule) (*ir.RateLimitRule, error) {
m := &ir.StringMatch{
Name: header.Name,
SafeRegex: header.Value,
+ Invert: header.Invert,
}
irRule.HeaderMatches = append(irRule.HeaderMatches, m)
case *header.Type == egv1a1.HeaderMatchDistinct && header.Value == nil:
+ if header.Invert != nil && *header.Invert {
+ return nil, fmt.Errorf("unable to translate rateLimit." +
+ "Invert is not applicable for distinct header match type")
+ }
m := &ir.StringMatch{
Name: header.Name,
Distinct: true,
@@ -798,365 +788,6 @@ func buildRateLimitRule(rule egv1a1.RateLimitRule) (*ir.RateLimitRule, error) {
return irRule, nil
}
-func (t *Translator) buildLoadBalancer(policy *egv1a1.BackendTrafficPolicy) (*ir.LoadBalancer, error) {
- var lb *ir.LoadBalancer
- switch policy.Spec.LoadBalancer.Type {
- case egv1a1.ConsistentHashLoadBalancerType:
- consistentHash, err := t.buildConsistentHashLoadBalancer(policy)
- if err != nil {
- return nil, perr.WithMessage(err, "ConsistentHash")
- }
-
- lb = &ir.LoadBalancer{
- ConsistentHash: consistentHash,
- }
- case egv1a1.LeastRequestLoadBalancerType:
- lb = &ir.LoadBalancer{}
- if policy.Spec.LoadBalancer.SlowStart != nil {
- if policy.Spec.LoadBalancer.SlowStart.Window != nil {
- lb.LeastRequest = &ir.LeastRequest{
- SlowStart: &ir.SlowStart{
- Window: policy.Spec.LoadBalancer.SlowStart.Window,
- },
- }
- }
- }
- case egv1a1.RandomLoadBalancerType:
- lb = &ir.LoadBalancer{
- Random: &ir.Random{},
- }
- case egv1a1.RoundRobinLoadBalancerType:
- lb = &ir.LoadBalancer{
- RoundRobin: &ir.RoundRobin{
- SlowStart: &ir.SlowStart{},
- },
- }
- if policy.Spec.LoadBalancer.SlowStart != nil {
- if policy.Spec.LoadBalancer.SlowStart.Window != nil {
- lb.RoundRobin = &ir.RoundRobin{
- SlowStart: &ir.SlowStart{
- Window: policy.Spec.LoadBalancer.SlowStart.Window,
- },
- }
- }
- }
- }
-
- return lb, nil
-}
-
-func (t *Translator) buildConsistentHashLoadBalancer(policy *egv1a1.BackendTrafficPolicy) (*ir.ConsistentHash, error) {
- consistentHash := &ir.ConsistentHash{}
-
- if policy.Spec.LoadBalancer.ConsistentHash.TableSize != nil {
- tableSize := policy.Spec.LoadBalancer.ConsistentHash.TableSize
-
- if *tableSize > MaxConsistentHashTableSize || !big.NewInt(int64(*tableSize)).ProbablyPrime(0) {
- return nil, fmt.Errorf("invalid TableSize value %d", *tableSize)
- }
-
- consistentHash.TableSize = tableSize
- }
-
- switch policy.Spec.LoadBalancer.ConsistentHash.Type {
- case egv1a1.SourceIPConsistentHashType:
- consistentHash.SourceIP = ptr.To(true)
- case egv1a1.HeaderConsistentHashType:
- consistentHash.Header = &ir.Header{
- Name: policy.Spec.LoadBalancer.ConsistentHash.Header.Name,
- }
- case egv1a1.CookieConsistentHashType:
- consistentHash.Cookie = policy.Spec.LoadBalancer.ConsistentHash.Cookie
- }
-
- return consistentHash, nil
-}
-
-func (t *Translator) buildProxyProtocol(policy *egv1a1.BackendTrafficPolicy) *ir.ProxyProtocol {
- var pp *ir.ProxyProtocol
- switch policy.Spec.ProxyProtocol.Version {
- case egv1a1.ProxyProtocolVersionV1:
- pp = &ir.ProxyProtocol{
- Version: ir.ProxyProtocolVersionV1,
- }
- case egv1a1.ProxyProtocolVersionV2:
- pp = &ir.ProxyProtocol{
- Version: ir.ProxyProtocolVersionV2,
- }
- }
-
- return pp
-}
-
-func (t *Translator) buildHealthCheck(policy *egv1a1.BackendTrafficPolicy) *ir.HealthCheck {
- if policy.Spec.HealthCheck == nil {
- return nil
- }
-
- irhc := &ir.HealthCheck{}
- if policy.Spec.HealthCheck.Passive != nil {
- irhc.Passive = t.buildPassiveHealthCheck(policy)
- }
-
- if policy.Spec.HealthCheck.Active != nil {
- irhc.Active = t.buildActiveHealthCheck(policy)
- }
-
- return irhc
-}
-
-func (t *Translator) buildPassiveHealthCheck(policy *egv1a1.BackendTrafficPolicy) *ir.OutlierDetection {
- if policy.Spec.HealthCheck == nil || policy.Spec.HealthCheck.Passive == nil {
- return nil
- }
-
- hc := policy.Spec.HealthCheck.Passive
- irOD := &ir.OutlierDetection{
- Interval: hc.Interval,
- SplitExternalLocalOriginErrors: hc.SplitExternalLocalOriginErrors,
- ConsecutiveLocalOriginFailures: hc.ConsecutiveLocalOriginFailures,
- ConsecutiveGatewayErrors: hc.ConsecutiveGatewayErrors,
- Consecutive5xxErrors: hc.Consecutive5xxErrors,
- BaseEjectionTime: hc.BaseEjectionTime,
- MaxEjectionPercent: hc.MaxEjectionPercent,
- }
- return irOD
-}
-
-func (t *Translator) buildActiveHealthCheck(policy *egv1a1.BackendTrafficPolicy) *ir.ActiveHealthCheck {
- if policy.Spec.HealthCheck == nil || policy.Spec.HealthCheck.Active == nil {
- return nil
- }
-
- hc := policy.Spec.HealthCheck.Active
- irHC := &ir.ActiveHealthCheck{
- Timeout: hc.Timeout,
- Interval: hc.Interval,
- UnhealthyThreshold: hc.UnhealthyThreshold,
- HealthyThreshold: hc.HealthyThreshold,
- }
- switch hc.Type {
- case egv1a1.ActiveHealthCheckerTypeHTTP:
- irHC.HTTP = t.buildHTTPActiveHealthChecker(hc.HTTP)
- case egv1a1.ActiveHealthCheckerTypeTCP:
- irHC.TCP = t.buildTCPActiveHealthChecker(hc.TCP)
- }
-
- return irHC
-}
-
-func (t *Translator) buildHTTPActiveHealthChecker(h *egv1a1.HTTPActiveHealthChecker) *ir.HTTPHealthChecker {
- if h == nil {
- return nil
- }
-
- irHTTP := &ir.HTTPHealthChecker{
- Path: h.Path,
- Method: h.Method,
- }
- if irHTTP.Method != nil {
- *irHTTP.Method = strings.ToUpper(*irHTTP.Method)
- }
-
- // deduplicate http statuses
- statusSet := sets.NewInt()
- for _, r := range h.ExpectedStatuses {
- statusSet.Insert(int(r))
- }
- irStatuses := make([]ir.HTTPStatus, 0, statusSet.Len())
-
- for _, r := range statusSet.List() {
- irStatuses = append(irStatuses, ir.HTTPStatus(r))
- }
- irHTTP.ExpectedStatuses = irStatuses
-
- irHTTP.ExpectedResponse = translateActiveHealthCheckPayload(h.ExpectedResponse)
- return irHTTP
-}
-
-func (t *Translator) buildTCPActiveHealthChecker(h *egv1a1.TCPActiveHealthChecker) *ir.TCPHealthChecker {
- if h == nil {
- return nil
- }
-
- irTCP := &ir.TCPHealthChecker{
- Send: translateActiveHealthCheckPayload(h.Send),
- Receive: translateActiveHealthCheckPayload(h.Receive),
- }
- return irTCP
-}
-
-func translateActiveHealthCheckPayload(p *egv1a1.ActiveHealthCheckPayload) *ir.HealthCheckPayload {
- if p == nil {
- return nil
- }
-
- irPayload := &ir.HealthCheckPayload{}
- switch p.Type {
- case egv1a1.ActiveHealthCheckPayloadTypeText:
- irPayload.Text = p.Text
- case egv1a1.ActiveHealthCheckPayloadTypeBinary:
- irPayload.Binary = make([]byte, len(p.Binary))
- copy(irPayload.Binary, p.Binary)
- }
-
- return irPayload
-}
-
-func ratelimitUnitToDuration(unit egv1a1.RateLimitUnit) int64 {
- var seconds int64
-
- switch unit {
- case egv1a1.RateLimitUnitSecond:
- seconds = 1
- case egv1a1.RateLimitUnitMinute:
- seconds = 60
- case egv1a1.RateLimitUnitHour:
- seconds = 60 * 60
- case egv1a1.RateLimitUnitDay:
- seconds = 60 * 60 * 24
- }
- return seconds
-}
-
-func (t *Translator) buildCircuitBreaker(policy *egv1a1.BackendTrafficPolicy) (*ir.CircuitBreaker, error) {
- var cb *ir.CircuitBreaker
- pcb := policy.Spec.CircuitBreaker
-
- if pcb != nil {
- cb = &ir.CircuitBreaker{}
-
- if pcb.MaxConnections != nil {
- if ui32, ok := int64ToUint32(*pcb.MaxConnections); ok {
- cb.MaxConnections = &ui32
- } else {
- return nil, fmt.Errorf("invalid MaxConnections value %d", *pcb.MaxConnections)
- }
- }
-
- if pcb.MaxParallelRequests != nil {
- if ui32, ok := int64ToUint32(*pcb.MaxParallelRequests); ok {
- cb.MaxParallelRequests = &ui32
- } else {
- return nil, fmt.Errorf("invalid MaxParallelRequests value %d", *pcb.MaxParallelRequests)
- }
- }
-
- if pcb.MaxPendingRequests != nil {
- if ui32, ok := int64ToUint32(*pcb.MaxPendingRequests); ok {
- cb.MaxPendingRequests = &ui32
- } else {
- return nil, fmt.Errorf("invalid MaxPendingRequests value %d", *pcb.MaxPendingRequests)
- }
- }
-
- if pcb.MaxParallelRetries != nil {
- if ui32, ok := int64ToUint32(*pcb.MaxParallelRetries); ok {
- cb.MaxParallelRetries = &ui32
- } else {
- return nil, fmt.Errorf("invalid MaxParallelRetries value %d", *pcb.MaxParallelRetries)
- }
- }
-
- if pcb.MaxRequestsPerConnection != nil {
- if ui32, ok := int64ToUint32(*pcb.MaxRequestsPerConnection); ok {
- cb.MaxRequestsPerConnection = &ui32
- } else {
- return nil, fmt.Errorf("invalid MaxRequestsPerConnection value %d", *pcb.MaxRequestsPerConnection)
- }
- }
-
- }
-
- return cb, nil
-}
-
-func (t *Translator) buildTimeout(policy *egv1a1.BackendTrafficPolicy, r *ir.HTTPRoute) (*ir.Timeout, error) {
- var (
- tto *ir.TCPTimeout
- hto *ir.HTTPTimeout
- terr bool
- errs error
- )
-
- pto := policy.Spec.Timeout
-
- if pto.TCP != nil && pto.TCP.ConnectTimeout != nil {
- d, err := time.ParseDuration(string(*pto.TCP.ConnectTimeout))
- if err != nil {
- terr = true
- errs = errors.Join(errs, fmt.Errorf("invalid ConnectTimeout value %s", *pto.TCP.ConnectTimeout))
- } else {
- tto = &ir.TCPTimeout{
- ConnectTimeout: ptr.To(metav1.Duration{Duration: d}),
- }
- }
- }
-
- if pto.HTTP != nil {
- var cit *metav1.Duration
- var mcd *metav1.Duration
-
- if pto.HTTP.ConnectionIdleTimeout != nil {
- d, err := time.ParseDuration(string(*pto.HTTP.ConnectionIdleTimeout))
- if err != nil {
- terr = true
- errs = errors.Join(errs, fmt.Errorf("invalid ConnectionIdleTimeout value %s", *pto.HTTP.ConnectionIdleTimeout))
- } else {
- cit = ptr.To(metav1.Duration{Duration: d})
- }
- }
-
- if pto.HTTP.MaxConnectionDuration != nil {
- d, err := time.ParseDuration(string(*pto.HTTP.MaxConnectionDuration))
- if err != nil {
- terr = true
- errs = errors.Join(errs, fmt.Errorf("invalid MaxConnectionDuration value %s", *pto.HTTP.MaxConnectionDuration))
- } else {
- mcd = ptr.To(metav1.Duration{Duration: d})
- }
- }
-
- hto = &ir.HTTPTimeout{
- ConnectionIdleTimeout: cit,
- MaxConnectionDuration: mcd,
- }
- }
-
- // http request timeout is translated during the gateway-api route resource translation
- // merge route timeout setting with backendtrafficpolicy timeout settings
- if terr {
- if r != nil && r.Traffic != nil && r.Traffic.Timeout != nil {
- return r.Traffic.Timeout.DeepCopy(), errs
- }
- } else {
- // http request timeout is translated during the gateway-api route resource translation
- // merge route timeout setting with backendtrafficpolicy timeout settings
- if r != nil &&
- r.Traffic != nil &&
- r.Traffic.Timeout != nil &&
- r.Traffic.Timeout.HTTP != nil &&
- r.Traffic.Timeout.HTTP.RequestTimeout != nil {
- if hto == nil {
- hto = &ir.HTTPTimeout{
- RequestTimeout: r.Traffic.Timeout.HTTP.RequestTimeout,
- }
- } else {
- hto.RequestTimeout = r.Traffic.Timeout.HTTP.RequestTimeout
- }
- }
-
- if hto != nil || tto != nil {
- return &ir.Timeout{
- TCP: tto,
- HTTP: hto,
- }, nil
- }
- }
-
- return nil, errs
-}
-
func int64ToUint32(in int64) (uint32, bool) {
if in >= 0 && in <= math.MaxUint32 {
return uint32(in), true
@@ -1164,31 +795,6 @@ func int64ToUint32(in int64) (uint32, bool) {
return 0, false
}
-func (t *Translator) buildBackendConnection(policy *egv1a1.BackendTrafficPolicy) (*ir.BackendConnection, error) {
- var (
- bcIR = &ir.BackendConnection{}
- bc = &egv1a1.BackendConnection{}
- )
-
- if policy.Spec.Connection != nil {
- bc = policy.Spec.Connection
-
- if bc.BufferLimit != nil {
- bf, ok := bc.BufferLimit.AsInt64()
- if !ok {
- return nil, fmt.Errorf("invalid BufferLimit value %s", bc.BufferLimit.String())
- }
- if bf < 0 || bf > math.MaxUint32 {
- return nil, fmt.Errorf("BufferLimit value %s is out of range", bc.BufferLimit.String())
- }
-
- bcIR.BufferLimitBytes = ptr.To(uint32(bf))
- }
- }
-
- return bcIR, nil
-}
-
func (t *Translator) buildFaultInjection(policy *egv1a1.BackendTrafficPolicy) *ir.FaultInjection {
var fi *ir.FaultInjection
if policy.Spec.FaultInjection != nil {
@@ -1216,97 +822,6 @@ func (t *Translator) buildFaultInjection(policy *egv1a1.BackendTrafficPolicy) *i
return fi
}
-func (t *Translator) buildTCPKeepAlive(policy *egv1a1.BackendTrafficPolicy) (*ir.TCPKeepalive, error) {
- var ka *ir.TCPKeepalive
- if policy.Spec.TCPKeepalive != nil {
- pka := policy.Spec.TCPKeepalive
- ka = &ir.TCPKeepalive{}
-
- if pka.Probes != nil {
- ka.Probes = pka.Probes
- }
-
- if pka.IdleTime != nil {
- d, err := time.ParseDuration(string(*pka.IdleTime))
- if err != nil {
- return nil, fmt.Errorf("invalid IdleTime value %s", *pka.IdleTime)
- }
- ka.IdleTime = ptr.To(uint32(d.Seconds()))
- }
-
- if pka.Interval != nil {
- d, err := time.ParseDuration(string(*pka.Interval))
- if err != nil {
- return nil, fmt.Errorf("invalid Interval value %s", *pka.Interval)
- }
- ka.Interval = ptr.To(uint32(d.Seconds()))
- }
-
- }
- return ka, nil
-}
-
-func (t *Translator) buildRetry(policy *egv1a1.BackendTrafficPolicy) *ir.Retry {
- var rt *ir.Retry
- if policy.Spec.Retry != nil {
- prt := policy.Spec.Retry
- rt = &ir.Retry{}
-
- if prt.NumRetries != nil {
- rt.NumRetries = ptr.To(uint32(*prt.NumRetries))
- }
-
- if prt.RetryOn != nil {
- ro := &ir.RetryOn{}
- bro := false
- if prt.RetryOn.HTTPStatusCodes != nil {
- ro.HTTPStatusCodes = makeIrStatusSet(prt.RetryOn.HTTPStatusCodes)
- bro = true
- }
-
- if prt.RetryOn.Triggers != nil {
- ro.Triggers = makeIrTriggerSet(prt.RetryOn.Triggers)
- bro = true
- }
-
- if bro {
- rt.RetryOn = ro
- }
- }
-
- if prt.PerRetry != nil {
- pr := &ir.PerRetryPolicy{}
- bpr := false
-
- if prt.PerRetry.Timeout != nil {
- pr.Timeout = prt.PerRetry.Timeout
- bpr = true
- }
-
- if prt.PerRetry.BackOff != nil {
- if prt.PerRetry.BackOff.MaxInterval != nil || prt.PerRetry.BackOff.BaseInterval != nil {
- bop := &ir.BackOffPolicy{}
- if prt.PerRetry.BackOff.MaxInterval != nil {
- bop.MaxInterval = prt.PerRetry.BackOff.MaxInterval
- }
-
- if prt.PerRetry.BackOff.BaseInterval != nil {
- bop.BaseInterval = prt.PerRetry.BackOff.BaseInterval
- }
- pr.BackOff = bop
- bpr = true
- }
- }
-
- if bpr {
- rt.PerRetry = pr
- }
- }
- }
-
- return rt
-}
-
func makeIrStatusSet(in []egv1a1.HTTPStatus) []ir.HTTPStatus {
statusSet := sets.NewInt()
for _, r := range in {
@@ -1332,3 +847,86 @@ func makeIrTriggerSet(in []egv1a1.TriggerEnum) []ir.TriggerEnum {
}
return irTriggers
}
+
+func buildResponseOverride(policy *egv1a1.BackendTrafficPolicy, resources *resource.Resources) (*ir.ResponseOverride, error) {
+ if len(policy.Spec.ResponseOverride) == 0 {
+ return nil, nil
+ }
+
+ rules := make([]ir.ResponseOverrideRule, 0, len(policy.Spec.ResponseOverride))
+ for index, ro := range policy.Spec.ResponseOverride {
+ match := ir.CustomResponseMatch{
+ StatusCodes: make([]ir.StatusCodeMatch, 0, len(ro.Match.StatusCodes)),
+ }
+
+ for _, code := range ro.Match.StatusCodes {
+ if code.Type != nil && *code.Type == egv1a1.StatusCodeValueTypeRange {
+ match.StatusCodes = append(match.StatusCodes, ir.StatusCodeMatch{
+ Range: &ir.StatusCodeRange{
+ Start: code.Range.Start,
+ End: code.Range.End,
+ },
+ })
+ } else {
+ match.StatusCodes = append(match.StatusCodes, ir.StatusCodeMatch{
+ Value: code.Value,
+ })
+ }
+ }
+
+ response := ir.CustomResponse{
+ ContentType: ro.Response.ContentType,
+ }
+
+ var err error
+ response.Body, err = getCustomResponseBody(ro.Response.Body, resources, policy.Namespace)
+ if err != nil {
+ return nil, err
+ }
+
+ rules = append(rules, ir.ResponseOverrideRule{
+ Name: defaultResponseOverrideRuleName(policy, index),
+ Match: match,
+ Response: response,
+ })
+ }
+ return &ir.ResponseOverride{
+ Name: irConfigName(policy),
+ Rules: rules,
+ }, nil
+}
+
+func getCustomResponseBody(body egv1a1.CustomResponseBody, resources *resource.Resources, policyNs string) (*string, error) {
+ if body.Type != nil && *body.Type == egv1a1.ResponseValueTypeValueRef {
+ cm := resources.GetConfigMap(policyNs, string(body.ValueRef.Name))
+ if cm != nil {
+ b, dataOk := cm.Data["response.body"]
+ switch {
+ case dataOk:
+ return &b, nil
+ case len(cm.Data) > 0: // Fallback to the first key if response.body is not found
+ for _, value := range cm.Data {
+ b = value
+ break
+ }
+ return &b, nil
+ default:
+ return nil, fmt.Errorf("can't find the key response.body in the referenced configmap %s", body.ValueRef.Name)
+ }
+
+ } else {
+ return nil, fmt.Errorf("can't find the referenced configmap %s", body.ValueRef.Name)
+ }
+ } else if body.Inline != nil {
+ return body.Inline, nil
+ }
+
+ return nil, nil
+}
+
+func defaultResponseOverrideRuleName(policy *egv1a1.BackendTrafficPolicy, index int) string {
+ return fmt.Sprintf(
+ "%s/responseoverride/rule/%s",
+ irConfigName(policy),
+ strconv.Itoa(index))
+}
diff --git a/internal/gatewayapi/backendtrafficpolicy_test.go b/internal/gatewayapi/backendtrafficpolicy_test.go
index d40d1e68c76..ebf721fb07d 100644
--- a/internal/gatewayapi/backendtrafficpolicy_test.go
+++ b/internal/gatewayapi/backendtrafficpolicy_test.go
@@ -46,7 +46,6 @@ func TestInt64ToUint32(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.Name, func(t *testing.T) {
out, success := int64ToUint32(tc.In)
require.Equal(t, tc.Out, out)
diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go
index e7e91dbcade..1c8d0f8af4a 100644
--- a/internal/gatewayapi/clienttrafficpolicy.go
+++ b/internal/gatewayapi/clienttrafficpolicy.go
@@ -18,9 +18,11 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/ptr"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils"
@@ -28,11 +30,7 @@ import (
const (
// Use an invalid string to represent all sections (listeners) within a Gateway
- AllSections = "/"
- MinHTTP2InitialStreamWindowSize = 65535 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size
- MaxHTTP2InitialStreamWindowSize = 2147483647 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size
- MinHTTP2InitialConnectionWindowSize = MinHTTP2InitialStreamWindowSize
- MaxHTTP2InitialConnectionWindowSize = MaxHTTP2InitialStreamWindowSize
+ AllSections = "/"
)
func hasSectionName(target *gwapiv1a2.LocalPolicyTargetReferenceWithSectionName) bool {
@@ -40,10 +38,10 @@ func hasSectionName(target *gwapiv1a2.LocalPolicyTargetReferenceWithSectionName)
}
func (t *Translator) ProcessClientTrafficPolicies(
- resources *Resources,
+ resources *resource.Resources,
gateways []*GatewayContext,
- xdsIR XdsIRMap,
- infraIR InfraIRMap,
+ xdsIR resource.XdsIRMap,
+ infraIR resource.InfraIRMap,
) []*egv1a1.ClientTrafficPolicy {
var res []*egv1a1.ClientTrafficPolicy
@@ -292,12 +290,10 @@ func resolveCTPolicyTargetRef(
targetRef *gwapiv1a2.LocalPolicyTargetReferenceWithSectionName,
gateways map[types.NamespacedName]*policyGatewayTargetContext,
) (*GatewayContext, *status.PolicyResolveError) {
- targetNs := policy.Namespace
-
// Check if the gateway exists
key := types.NamespacedName{
Name: string(targetRef.Name),
- Namespace: targetNs,
+ Namespace: policy.Namespace,
}
gateway, ok := gateways[key]
@@ -306,17 +302,6 @@ func resolveCTPolicyTargetRef(
return nil, nil
}
- // Ensure Policy and target Gateway are in the same namespace
- if policy.Namespace != targetNs {
- message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, ClientTrafficPolicy can only target a Gateway in the same namespace.",
- policy.Namespace, targetNs)
-
- return gateway.GatewayContext, &status.PolicyResolveError{
- Reason: gwapiv1a2.PolicyReasonInvalid,
- Message: message,
- }
- }
-
// If sectionName is set, make sure its valid
sectionName := targetRef.SectionName
if sectionName != nil {
@@ -382,7 +367,7 @@ func validatePortOverlapForClientTrafficPolicy(l *ListenerContext, xds *ir.Xds,
}
func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.ClientTrafficPolicy, l *ListenerContext,
- xdsIR XdsIRMap, infraIR InfraIRMap, resources *Resources,
+ xdsIR resource.XdsIRMap, infraIR resource.InfraIRMap, resources *resource.Resources,
) error {
// Find IR
irKey := t.getIRKey(l.gateway.Gateway)
@@ -434,7 +419,7 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie
}
// Translate Proxy Protocol
- enableProxyProtocol = buildProxyProtocol(policy.Spec.EnableProxyProtocol)
+ enableProxyProtocol = ptr.Deref(policy.Spec.EnableProxyProtocol, false)
// Translate Client Timeout Settings
timeout, err = buildClientTimeout(policy.Spec.Timeout)
@@ -449,7 +434,10 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie
translateClientIPDetection(policy.Spec.ClientIPDetection, httpIR)
// Translate Header Settings
- translateListenerHeaderSettings(policy.Spec.Headers, httpIR)
+ if err = translateListenerHeaderSettings(policy.Spec.Headers, httpIR); err != nil {
+ err = perr.WithMessage(err, "Headers")
+ errs = errors.Join(errs, err)
+ }
// Translate Path Settings
translatePathSettings(policy.Spec.Path, httpIR)
@@ -621,14 +609,6 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout,
return irClientTimeout, nil
}
-func buildProxyProtocol(enableProxyProtocol *bool) bool {
- if enableProxyProtocol != nil && *enableProxyProtocol {
- return true
- }
-
- return false
-}
-
func translateClientIPDetection(clientIPDetection *egv1a1.ClientIPDetectionSettings, httpIR *ir.HTTPListener) {
// Return early if not set
if clientIPDetection == nil {
@@ -638,9 +618,9 @@ func translateClientIPDetection(clientIPDetection *egv1a1.ClientIPDetectionSetti
httpIR.ClientIPDetection = (*ir.ClientIPDetectionSettings)(clientIPDetection)
}
-func translateListenerHeaderSettings(headerSettings *egv1a1.HeaderSettings, httpIR *ir.HTTPListener) {
+func translateListenerHeaderSettings(headerSettings *egv1a1.HeaderSettings, httpIR *ir.HTTPListener) error {
if headerSettings == nil {
- return
+ return nil
}
httpIR.Headers = &ir.HeaderSettings{
EnableEnvoyHeaders: ptr.Deref(headerSettings.EnableEnvoyHeaders, false),
@@ -659,6 +639,16 @@ func translateListenerHeaderSettings(headerSettings *egv1a1.HeaderSettings, http
httpIR.Headers.XForwardedClientCert.CertDetailsToAdd = headerSettings.XForwardedClientCert.CertDetailsToAdd
}
}
+
+ if headerSettings.EarlyRequestHeaders != nil {
+ headersToAdd, headersToRemove, err := translateEarlyRequestHeaders(headerSettings.EarlyRequestHeaders)
+ if err != nil {
+ return err
+ }
+ httpIR.Headers.EarlyAddRequestHeaders = headersToAdd
+ httpIR.Headers.EarlyRemoveRequestHeaders = headersToRemove
+ }
+ return nil
}
func translateHTTP1Settings(http1Settings *egv1a1.HTTP1Settings, httpIR *ir.HTTPListener) error {
@@ -672,6 +662,7 @@ func translateHTTP1Settings(http1Settings *egv1a1.HTTP1Settings, httpIR *ir.HTTP
if http1Settings.HTTP10 != nil {
var defaultHost *string
if ptr.Deref(http1Settings.HTTP10.UseDefaultHost, false) {
+ // First level of precedence - the first non-wildcard hostname associated with the listener
for _, hostname := range httpIR.Hostnames {
if !strings.Contains(hostname, "*") {
// make linter happy
@@ -680,8 +671,27 @@ func translateHTTP1Settings(http1Settings *egv1a1.HTTP1Settings, httpIR *ir.HTTP
break
}
}
+ // second level of precedence - try to get a hostname from the HTTPRoutes
+ numMatchingRoutes := 0
if defaultHost == nil {
- return fmt.Errorf("cannot set http10 default host on listener with only wildcard hostnames")
+ // When taken from the routes, a default hostname can only be chosen if there
+ // is exactly one HTTPRoute with a non-wildcard hostname configured.
+ for _, route := range httpIR.Routes {
+ if route.Hostname != "" && !strings.Contains(route.Hostname, "*") {
+ numMatchingRoutes++
+ // make the linter happy
+ theHost := route.Hostname
+ defaultHost = ptr.To(theHost)
+ }
+ if numMatchingRoutes > 1 {
+ break
+ }
+ }
+ if numMatchingRoutes == 0 {
+ return fmt.Errorf("cannot set http10 default host on listener with only wildcard hostnames")
+ } else if numMatchingRoutes > 1 {
+ return fmt.Errorf("cannot set http10 default host on listener with only wildcard hostnames and more than one possible default route")
+ }
}
}
// If useDefaultHost was set, then defaultHost will have the hostname to use.
@@ -749,7 +759,7 @@ func translateHealthCheckSettings(healthCheckSettings *egv1a1.HealthCheckSetting
}
func (t *Translator) buildListenerTLSParameters(policy *egv1a1.ClientTrafficPolicy,
- irTLSConfig *ir.TLSConfig, resources *Resources,
+ irTLSConfig *ir.TLSConfig, resources *resource.Resources,
) (*ir.TLSConfig, error) {
// Return if this listener isn't a TLS listener. There has to be
// at least one certificate defined, which would cause httpIR/tcpIR to
@@ -770,7 +780,7 @@ func (t *Translator) buildListenerTLSParameters(policy *egv1a1.ClientTrafficPoli
return irTLSConfig, nil
}
- if len(tlsParams.ALPNProtocols) > 0 {
+ if tlsParams.ALPNProtocols != nil {
irTLSConfig.ALPNProtocols = make([]string, len(tlsParams.ALPNProtocols))
for i := range tlsParams.ALPNProtocols {
irTLSConfig.ALPNProtocols[i] = string(tlsParams.ALPNProtocols[i])
@@ -796,7 +806,7 @@ func (t *Translator) buildListenerTLSParameters(policy *egv1a1.ClientTrafficPoli
if tlsParams.ClientValidation != nil {
from := crossNamespaceFrom{
group: egv1a1.GroupName,
- kind: KindClientTrafficPolicy,
+ kind: resource.KindClientTrafficPolicy,
namespace: policy.Namespace,
}
@@ -805,7 +815,7 @@ func (t *Translator) buildListenerTLSParameters(policy *egv1a1.ClientTrafficPoli
}
for _, caCertRef := range tlsParams.ClientValidation.CACertificateRefs {
- if caCertRef.Kind == nil || string(*caCertRef.Kind) == KindSecret { // nolint
+ if caCertRef.Kind == nil || string(*caCertRef.Kind) == resource.KindSecret { // nolint
secret, err := t.validateSecretRef(false, from, caCertRef, resources)
if err != nil {
return irTLSConfig, err
@@ -824,7 +834,7 @@ func (t *Translator) buildListenerTLSParameters(policy *egv1a1.ClientTrafficPoli
irCACert.Certificate = append(irCACert.Certificate, secretBytes...)
- } else if string(*caCertRef.Kind) == KindConfigMap {
+ } else if string(*caCertRef.Kind) == resource.KindConfigMap {
configMap, err := t.validateConfigMapRef(false, from, caCertRef, resources)
if err != nil {
return irTLSConfig, err
@@ -854,6 +864,15 @@ func (t *Translator) buildListenerTLSParameters(policy *egv1a1.ClientTrafficPoli
}
}
+ if tlsParams.Session != nil && tlsParams.Session.Resumption != nil {
+ if tlsParams.Session.Resumption.Stateless != nil {
+ irTLSConfig.StatelessSessionResumption = true
+ }
+ if tlsParams.Session.Resumption.Stateful != nil {
+ irTLSConfig.StatefulSessionResumption = true
+ }
+ }
+
return irTLSConfig, nil
}
@@ -894,3 +913,130 @@ func buildConnection(connection *egv1a1.ClientConnection) (*ir.ClientConnection,
return irConnection, nil
}
+
+func translateEarlyRequestHeaders(headerModifier *gwapiv1.HTTPHeaderFilter) ([]ir.AddHeader, []string, error) {
+ // Make sure the header modifier config actually exists
+ if headerModifier == nil {
+ return nil, nil, nil
+ }
+ var errs error
+ emptyFilterConfig := true // keep track of whether the provided config is empty or not
+
+ var AddRequestHeaders []ir.AddHeader
+ var RemoveRequestHeaders []string
+
+ // Add request headers
+ if headersToAdd := headerModifier.Add; headersToAdd != nil {
+ if len(headersToAdd) > 0 {
+ emptyFilterConfig = false
+ }
+ for _, addHeader := range headersToAdd {
+ emptyFilterConfig = false
+ if addHeader.Name == "" {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders cannot add a header with an empty name"))
+ // try to process the rest of the headers and produce a valid config.
+ continue
+ }
+ // Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names
+ if strings.ContainsAny(string(addHeader.Name), "/:") {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders Filter cannot set headers with a '/' or ':' character in them. Header: %q", string(addHeader.Name)))
+ continue
+ }
+ // Check if the header is a duplicate
+ headerKey := string(addHeader.Name)
+ canAddHeader := true
+ for _, h := range AddRequestHeaders {
+ if strings.EqualFold(h.Name, headerKey) {
+ canAddHeader = false
+ break
+ }
+ }
+
+ if !canAddHeader {
+ continue
+ }
+
+ newHeader := ir.AddHeader{
+ Name: headerKey,
+ Append: true,
+ Value: strings.Split(addHeader.Value, ","),
+ }
+
+ AddRequestHeaders = append(AddRequestHeaders, newHeader)
+ }
+ }
+
+ // Set headers
+ if headersToSet := headerModifier.Set; headersToSet != nil {
+ if len(headersToSet) > 0 {
+ emptyFilterConfig = false
+ }
+ for _, setHeader := range headersToSet {
+
+ if setHeader.Name == "" {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders cannot set a header with an empty name"))
+ continue
+ }
+ // Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names
+ if strings.ContainsAny(string(setHeader.Name), "/:") {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders cannot set headers with a '/' or ':' character in them. Header: '%s'", string(setHeader.Name)))
+ continue
+ }
+
+ // Check if the header to be set has already been configured
+ headerKey := string(setHeader.Name)
+ canAddHeader := true
+ for _, h := range AddRequestHeaders {
+ if strings.EqualFold(h.Name, headerKey) {
+ canAddHeader = false
+ break
+ }
+ }
+ if !canAddHeader {
+ continue
+ }
+ newHeader := ir.AddHeader{
+ Name: string(setHeader.Name),
+ Append: false,
+ Value: strings.Split(setHeader.Value, ","),
+ }
+
+ AddRequestHeaders = append(AddRequestHeaders, newHeader)
+ }
+ }
+
+ // Remove request headers
+ // As far as Envoy is concerned, it is ok to configure a header to be added/set and also in the list of
+ // headers to remove. It will remove the original header if present and then add/set the header after.
+ if headersToRemove := headerModifier.Remove; headersToRemove != nil {
+ if len(headersToRemove) > 0 {
+ emptyFilterConfig = false
+ }
+ for _, removedHeader := range headersToRemove {
+ if removedHeader == "" {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders cannot remove a header with an empty name"))
+ continue
+ }
+
+ canRemHeader := true
+ for _, h := range RemoveRequestHeaders {
+ if strings.EqualFold(h, removedHeader) {
+ canRemHeader = false
+ break
+ }
+ }
+ if !canRemHeader {
+ continue
+ }
+
+ RemoveRequestHeaders = append(RemoveRequestHeaders, removedHeader)
+ }
+ }
+
+ // Update the status if the filter failed to configure any valid headers to add/remove
+ if len(AddRequestHeaders) == 0 && len(RemoveRequestHeaders) == 0 && !emptyFilterConfig {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders did not provide valid configuration to add/set/remove any headers"))
+ }
+
+ return AddRequestHeaders, RemoveRequestHeaders, errs
+}
diff --git a/internal/gatewayapi/clustersettings.go b/internal/gatewayapi/clustersettings.go
new file mode 100644
index 00000000000..40266553b46
--- /dev/null
+++ b/internal/gatewayapi/clustersettings.go
@@ -0,0 +1,538 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package gatewayapi
+
+import (
+ "errors"
+ "fmt"
+ "math"
+ "math/big"
+ "net/http"
+ "strings"
+ "time"
+
+ perr "github.com/pkg/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/util/sets"
+ "k8s.io/utils/ptr"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/ir"
+)
+
+func translateTrafficFeatures(policy *egv1a1.ClusterSettings) (*ir.TrafficFeatures, error) {
+ if policy == nil {
+ return nil, nil
+ }
+ ret := &ir.TrafficFeatures{}
+
+ if timeout, err := buildClusterSettingsTimeout(*policy); err != nil {
+ return nil, err
+ } else {
+ ret.Timeout = timeout
+ }
+
+ if bc, err := buildBackendConnection(*policy); err != nil {
+ return nil, err
+ } else {
+ ret.BackendConnection = bc
+ }
+
+ if ka, err := buildTCPKeepAlive(*policy); err != nil {
+ return nil, err
+ } else {
+ ret.TCPKeepalive = ka
+ }
+
+ if cb, err := buildCircuitBreaker(*policy); err != nil {
+ return nil, err
+ } else {
+ ret.CircuitBreaker = cb
+ }
+
+ if lb, err := buildLoadBalancer(*policy); err != nil {
+ return nil, err
+ } else {
+ ret.LoadBalancer = lb
+ }
+
+ ret.ProxyProtocol = buildProxyProtocol(*policy)
+
+ ret.HealthCheck = buildHealthCheck(*policy)
+
+ ret.DNS = translateDNS(*policy)
+
+ if h2, err := buildIRHTTP2Settings(policy.HTTP2); err != nil {
+ return nil, err
+ } else {
+ ret.HTTP2 = h2
+ }
+
+ ret.Retry = buildRetry(policy.Retry)
+
+ // If nothing was set in any of the above calls, return nil instead of an empty
+ // container
+ var empty ir.TrafficFeatures
+ if empty == *ret {
+ ret = nil
+ }
+
+ return ret, nil
+}
+
+func buildClusterSettingsTimeout(policy egv1a1.ClusterSettings) (*ir.Timeout, error) {
+ if policy.Timeout == nil {
+ return nil, nil
+ }
+
+ var (
+ errs error
+ to = &ir.Timeout{}
+ pto = policy.Timeout
+ )
+
+ if pto.TCP != nil && pto.TCP.ConnectTimeout != nil {
+ d, err := time.ParseDuration(string(*pto.TCP.ConnectTimeout))
+ if err != nil {
+ errs = errors.Join(errs, fmt.Errorf("invalid ConnectTimeout value %s", *pto.TCP.ConnectTimeout))
+ } else {
+ to.TCP = &ir.TCPTimeout{
+ ConnectTimeout: ptr.To(metav1.Duration{Duration: d}),
+ }
+ }
+ }
+
+ if pto.HTTP != nil {
+ var cit *metav1.Duration
+ var mcd *metav1.Duration
+ var rt *metav1.Duration
+
+ if pto.HTTP.ConnectionIdleTimeout != nil {
+ d, err := time.ParseDuration(string(*pto.HTTP.ConnectionIdleTimeout))
+ if err != nil {
+ errs = errors.Join(errs, fmt.Errorf("invalid ConnectionIdleTimeout value %s", *pto.HTTP.ConnectionIdleTimeout))
+ } else {
+ cit = ptr.To(metav1.Duration{Duration: d})
+ }
+ }
+
+ if pto.HTTP.MaxConnectionDuration != nil {
+ d, err := time.ParseDuration(string(*pto.HTTP.MaxConnectionDuration))
+ if err != nil {
+ errs = errors.Join(errs, fmt.Errorf("invalid MaxConnectionDuration value %s", *pto.HTTP.MaxConnectionDuration))
+ } else {
+ mcd = ptr.To(metav1.Duration{Duration: d})
+ }
+ }
+
+ if pto.HTTP.RequestTimeout != nil {
+ d, err := time.ParseDuration(string(*pto.HTTP.RequestTimeout))
+ if err != nil {
+ errs = errors.Join(errs, fmt.Errorf("invalid RequestTimeout value %s", *pto.HTTP.RequestTimeout))
+ } else {
+ rt = ptr.To(metav1.Duration{Duration: d})
+ }
+ }
+
+ to.HTTP = &ir.HTTPTimeout{
+ ConnectionIdleTimeout: cit,
+ MaxConnectionDuration: mcd,
+ RequestTimeout: rt,
+ }
+ }
+ return to, errs
+}
+
+func buildBackendConnection(policy egv1a1.ClusterSettings) (*ir.BackendConnection, error) {
+ if policy.Connection == nil {
+ return nil, nil
+ }
+ var (
+ bcIR = &ir.BackendConnection{}
+ bc = &egv1a1.BackendConnection{}
+ )
+
+ if policy.Connection != nil {
+ bc = policy.Connection
+
+ if bc.BufferLimit != nil {
+ bf, ok := bc.BufferLimit.AsInt64()
+ if !ok {
+ return nil, fmt.Errorf("invalid BufferLimit value %s", bc.BufferLimit.String())
+ }
+ if bf < 0 || bf > math.MaxUint32 {
+ return nil, fmt.Errorf("BufferLimit value %s is out of range", bc.BufferLimit.String())
+ }
+
+ bcIR.BufferLimitBytes = ptr.To(uint32(bf))
+ }
+ }
+
+ return bcIR, nil
+}
+
+func buildTCPKeepAlive(policy egv1a1.ClusterSettings) (*ir.TCPKeepalive, error) {
+ if policy.TCPKeepalive == nil {
+ return nil, nil
+ }
+
+ pka := policy.TCPKeepalive
+ ka := &ir.TCPKeepalive{}
+
+ if pka.Probes != nil {
+ ka.Probes = pka.Probes
+ }
+
+ if pka.IdleTime != nil {
+ d, err := time.ParseDuration(string(*pka.IdleTime))
+ if err != nil {
+ return nil, fmt.Errorf("invalid IdleTime value %s", *pka.IdleTime)
+ }
+ ka.IdleTime = ptr.To(uint32(d.Seconds()))
+ }
+
+ if pka.Interval != nil {
+ d, err := time.ParseDuration(string(*pka.Interval))
+ if err != nil {
+ return nil, fmt.Errorf("invalid Interval value %s", *pka.Interval)
+ }
+ ka.Interval = ptr.To(uint32(d.Seconds()))
+ }
+ return ka, nil
+}
+
+func buildCircuitBreaker(policy egv1a1.ClusterSettings) (*ir.CircuitBreaker, error) {
+ if policy.CircuitBreaker == nil {
+ return nil, nil
+ }
+
+ var cb *ir.CircuitBreaker
+ pcb := policy.CircuitBreaker
+
+ if pcb != nil {
+ cb = &ir.CircuitBreaker{}
+
+ if pcb.MaxConnections != nil {
+ if ui32, ok := int64ToUint32(*pcb.MaxConnections); ok {
+ cb.MaxConnections = &ui32
+ } else {
+ return nil, fmt.Errorf("invalid MaxConnections value %d", *pcb.MaxConnections)
+ }
+ }
+
+ if pcb.MaxParallelRequests != nil {
+ if ui32, ok := int64ToUint32(*pcb.MaxParallelRequests); ok {
+ cb.MaxParallelRequests = &ui32
+ } else {
+ return nil, fmt.Errorf("invalid MaxParallelRequests value %d", *pcb.MaxParallelRequests)
+ }
+ }
+
+ if pcb.MaxPendingRequests != nil {
+ if ui32, ok := int64ToUint32(*pcb.MaxPendingRequests); ok {
+ cb.MaxPendingRequests = &ui32
+ } else {
+ return nil, fmt.Errorf("invalid MaxPendingRequests value %d", *pcb.MaxPendingRequests)
+ }
+ }
+
+ if pcb.MaxParallelRetries != nil {
+ if ui32, ok := int64ToUint32(*pcb.MaxParallelRetries); ok {
+ cb.MaxParallelRetries = &ui32
+ } else {
+ return nil, fmt.Errorf("invalid MaxParallelRetries value %d", *pcb.MaxParallelRetries)
+ }
+ }
+
+ if pcb.MaxRequestsPerConnection != nil {
+ if ui32, ok := int64ToUint32(*pcb.MaxRequestsPerConnection); ok {
+ cb.MaxRequestsPerConnection = &ui32
+ } else {
+ return nil, fmt.Errorf("invalid MaxRequestsPerConnection value %d", *pcb.MaxRequestsPerConnection)
+ }
+ }
+
+ }
+
+ return cb, nil
+}
+
+func buildLoadBalancer(policy egv1a1.ClusterSettings) (*ir.LoadBalancer, error) {
+ if policy.LoadBalancer == nil {
+ return nil, nil
+ }
+ var lb *ir.LoadBalancer
+ switch policy.LoadBalancer.Type {
+ case egv1a1.ConsistentHashLoadBalancerType:
+ consistentHash, err := buildConsistentHashLoadBalancer(*policy.LoadBalancer)
+ if err != nil {
+ return nil, perr.WithMessage(err, "ConsistentHash")
+ }
+
+ lb = &ir.LoadBalancer{
+ ConsistentHash: consistentHash,
+ }
+ case egv1a1.LeastRequestLoadBalancerType:
+ lb = &ir.LoadBalancer{
+ LeastRequest: &ir.LeastRequest{},
+ }
+ if policy.LoadBalancer.SlowStart != nil && policy.LoadBalancer.SlowStart.Window != nil {
+ lb.LeastRequest.SlowStart = &ir.SlowStart{
+ Window: policy.LoadBalancer.SlowStart.Window,
+ }
+ }
+ case egv1a1.RandomLoadBalancerType:
+ lb = &ir.LoadBalancer{
+ Random: &ir.Random{},
+ }
+ case egv1a1.RoundRobinLoadBalancerType:
+ lb = &ir.LoadBalancer{
+ RoundRobin: &ir.RoundRobin{},
+ }
+ if policy.LoadBalancer.SlowStart != nil && policy.LoadBalancer.SlowStart.Window != nil {
+ lb.RoundRobin.SlowStart = &ir.SlowStart{
+ Window: policy.LoadBalancer.SlowStart.Window,
+ }
+ }
+ }
+
+ return lb, nil
+}
+
+func buildConsistentHashLoadBalancer(policy egv1a1.LoadBalancer) (*ir.ConsistentHash, error) {
+ consistentHash := &ir.ConsistentHash{}
+
+ if policy.ConsistentHash.TableSize != nil {
+ tableSize := policy.ConsistentHash.TableSize
+
+ if *tableSize > MaxConsistentHashTableSize || !big.NewInt(int64(*tableSize)).ProbablyPrime(0) {
+ return nil, fmt.Errorf("invalid TableSize value %d", *tableSize)
+ }
+
+ consistentHash.TableSize = tableSize
+ }
+
+ switch policy.ConsistentHash.Type {
+ case egv1a1.SourceIPConsistentHashType:
+ consistentHash.SourceIP = ptr.To(true)
+ case egv1a1.HeaderConsistentHashType:
+ consistentHash.Header = &ir.Header{
+ Name: policy.ConsistentHash.Header.Name,
+ }
+ case egv1a1.CookieConsistentHashType:
+ consistentHash.Cookie = policy.ConsistentHash.Cookie
+ }
+
+ return consistentHash, nil
+}
+
+func buildProxyProtocol(policy egv1a1.ClusterSettings) *ir.ProxyProtocol {
+ if policy.ProxyProtocol == nil {
+ return nil
+ }
+ var pp *ir.ProxyProtocol
+ switch policy.ProxyProtocol.Version {
+ case egv1a1.ProxyProtocolVersionV1:
+ pp = &ir.ProxyProtocol{
+ Version: ir.ProxyProtocolVersionV1,
+ }
+ case egv1a1.ProxyProtocolVersionV2:
+ pp = &ir.ProxyProtocol{
+ Version: ir.ProxyProtocolVersionV2,
+ }
+ }
+
+ return pp
+}
+
+func buildHealthCheck(policy egv1a1.ClusterSettings) *ir.HealthCheck {
+ if policy.HealthCheck == nil {
+ return nil
+ }
+
+ irhc := &ir.HealthCheck{}
+ irhc.Passive = buildPassiveHealthCheck(*policy.HealthCheck)
+ irhc.Active = buildActiveHealthCheck(*policy.HealthCheck)
+
+ return irhc
+}
+
+func buildPassiveHealthCheck(policy egv1a1.HealthCheck) *ir.OutlierDetection {
+ if policy.Passive == nil {
+ return nil
+ }
+
+ hc := policy.Passive
+ irOD := &ir.OutlierDetection{
+ Interval: hc.Interval,
+ SplitExternalLocalOriginErrors: hc.SplitExternalLocalOriginErrors,
+ ConsecutiveLocalOriginFailures: hc.ConsecutiveLocalOriginFailures,
+ ConsecutiveGatewayErrors: hc.ConsecutiveGatewayErrors,
+ Consecutive5xxErrors: hc.Consecutive5xxErrors,
+ BaseEjectionTime: hc.BaseEjectionTime,
+ MaxEjectionPercent: hc.MaxEjectionPercent,
+ }
+ return irOD
+}
+
+func buildActiveHealthCheck(policy egv1a1.HealthCheck) *ir.ActiveHealthCheck {
+ if policy.Active == nil {
+ return nil
+ }
+
+ hc := policy.Active
+ irHC := &ir.ActiveHealthCheck{
+ Timeout: hc.Timeout,
+ Interval: hc.Interval,
+ UnhealthyThreshold: hc.UnhealthyThreshold,
+ HealthyThreshold: hc.HealthyThreshold,
+ }
+ switch hc.Type {
+ case egv1a1.ActiveHealthCheckerTypeHTTP:
+ irHC.HTTP = buildHTTPActiveHealthChecker(hc.HTTP)
+ case egv1a1.ActiveHealthCheckerTypeTCP:
+ irHC.TCP = buildTCPActiveHealthChecker(hc.TCP)
+ case egv1a1.ActiveHealthCheckerTypeGRPC:
+ irHC.GRPC = &ir.GRPCHealthChecker{
+ Service: ptr.Deref(hc.GRPC, egv1a1.GRPCActiveHealthChecker{}).Service,
+ }
+ }
+
+ return irHC
+}
+
+func buildHTTPActiveHealthChecker(h *egv1a1.HTTPActiveHealthChecker) *ir.HTTPHealthChecker {
+ if h == nil {
+ return nil
+ }
+
+ irHTTP := &ir.HTTPHealthChecker{
+ Path: h.Path,
+ Method: h.Method,
+ }
+ if irHTTP.Method != nil {
+ *irHTTP.Method = strings.ToUpper(*irHTTP.Method)
+ }
+
+ // deduplicate http statuses
+ statusSet := sets.NewInt()
+ for _, r := range h.ExpectedStatuses {
+ statusSet.Insert(int(r))
+ }
+ // If no ExpectedStatus was set, use the default value (200)
+ if statusSet.Len() == 0 {
+ statusSet.Insert(http.StatusOK)
+ }
+ irStatuses := make([]ir.HTTPStatus, 0, statusSet.Len())
+
+ for _, r := range statusSet.List() {
+ irStatuses = append(irStatuses, ir.HTTPStatus(r))
+ }
+ irHTTP.ExpectedStatuses = irStatuses
+
+ irHTTP.ExpectedResponse = translateActiveHealthCheckPayload(h.ExpectedResponse)
+ return irHTTP
+}
+
+func buildTCPActiveHealthChecker(h *egv1a1.TCPActiveHealthChecker) *ir.TCPHealthChecker {
+ if h == nil {
+ return nil
+ }
+
+ irTCP := &ir.TCPHealthChecker{
+ Send: translateActiveHealthCheckPayload(h.Send),
+ Receive: translateActiveHealthCheckPayload(h.Receive),
+ }
+ return irTCP
+}
+
+func translateActiveHealthCheckPayload(p *egv1a1.ActiveHealthCheckPayload) *ir.HealthCheckPayload {
+ if p == nil {
+ return nil
+ }
+
+ irPayload := &ir.HealthCheckPayload{}
+ switch p.Type {
+ case egv1a1.ActiveHealthCheckPayloadTypeText:
+ irPayload.Text = p.Text
+ case egv1a1.ActiveHealthCheckPayloadTypeBinary:
+ irPayload.Binary = make([]byte, len(p.Binary))
+ copy(irPayload.Binary, p.Binary)
+ }
+
+ return irPayload
+}
+
+func translateDNS(policy egv1a1.ClusterSettings) *ir.DNS {
+ if policy.DNS == nil {
+ return nil
+ }
+ return &ir.DNS{
+ RespectDNSTTL: policy.DNS.RespectDNSTTL,
+ DNSRefreshRate: policy.DNS.DNSRefreshRate,
+ }
+}
+
+func buildRetry(r *egv1a1.Retry) *ir.Retry {
+ if r == nil {
+ return nil
+ }
+
+ rt := &ir.Retry{}
+
+ if r.NumRetries != nil {
+ rt.NumRetries = ptr.To(uint32(*r.NumRetries))
+ }
+
+ if r.RetryOn != nil {
+ ro := &ir.RetryOn{}
+ bro := false
+ if r.RetryOn.HTTPStatusCodes != nil {
+ ro.HTTPStatusCodes = makeIrStatusSet(r.RetryOn.HTTPStatusCodes)
+ bro = true
+ }
+
+ if r.RetryOn.Triggers != nil {
+ ro.Triggers = makeIrTriggerSet(r.RetryOn.Triggers)
+ bro = true
+ }
+
+ if bro {
+ rt.RetryOn = ro
+ }
+ }
+
+ if r.PerRetry != nil {
+ pr := &ir.PerRetryPolicy{}
+ bpr := false
+
+ if r.PerRetry.Timeout != nil {
+ pr.Timeout = r.PerRetry.Timeout
+ bpr = true
+ }
+
+ if r.PerRetry.BackOff != nil {
+ if r.PerRetry.BackOff.MaxInterval != nil || r.PerRetry.BackOff.BaseInterval != nil {
+ bop := &ir.BackOffPolicy{}
+ if r.PerRetry.BackOff.MaxInterval != nil {
+ bop.MaxInterval = r.PerRetry.BackOff.MaxInterval
+ }
+
+ if r.PerRetry.BackOff.BaseInterval != nil {
+ bop.BaseInterval = r.PerRetry.BackOff.BaseInterval
+ }
+ pr.BackOff = bop
+ bpr = true
+ }
+ }
+
+ if bpr {
+ rt.PerRetry = pr
+ }
+ }
+
+ return rt
+}
diff --git a/internal/gatewayapi/conformance/suite.go b/internal/gatewayapi/conformance/suite.go
index 4637e023779..90181246b69 100644
--- a/internal/gatewayapi/conformance/suite.go
+++ b/internal/gatewayapi/conformance/suite.go
@@ -15,7 +15,7 @@ import (
// SkipTests is a list of tests that are skipped in the conformance suite.
var SkipTests = []suite.ConformanceTest{
tests.GatewayStaticAddresses,
- tests.GatewayHTTPListenerIsolation, // https://github.com/envoyproxy/gateway/issues/3352
+ tests.GatewayInfrastructure,
}
func skipTestsShortNames(skipTests []suite.ConformanceTest) []string {
@@ -28,9 +28,26 @@ func skipTestsShortNames(skipTests []suite.ConformanceTest) []string {
// EnvoyGatewaySuite is the conformance suite configuration for the Gateway API.
var EnvoyGatewaySuite = suite.ConformanceOptions{
- SupportedFeatures: features.AllFeatures,
- ExemptFeatures: sets.New[features.SupportedFeature]().
- Insert(features.MeshCoreFeatures.UnsortedList()...).
- Insert(features.MeshExtendedFeatures.UnsortedList()...),
- SkipTests: skipTestsShortNames(SkipTests),
+ SupportedFeatures: allFeatures(),
+ ExemptFeatures: meshFeatures(),
+ SkipTests: skipTestsShortNames(SkipTests),
+}
+
+func allFeatures() sets.Set[features.FeatureName] {
+ allFeatures := sets.New[features.FeatureName]()
+ for _, feature := range features.AllFeatures.UnsortedList() {
+ allFeatures.Insert(feature.Name)
+ }
+ return allFeatures
+}
+
+func meshFeatures() sets.Set[features.FeatureName] {
+ meshFeatures := sets.New[features.FeatureName]()
+ for _, feature := range features.MeshCoreFeatures.UnsortedList() {
+ meshFeatures.Insert(feature.Name)
+ }
+ for _, feature := range features.MeshExtendedFeatures.UnsortedList() {
+ meshFeatures.Insert(feature.Name)
+ }
+ return meshFeatures
}
diff --git a/internal/gatewayapi/conformance/support_level.go b/internal/gatewayapi/conformance/support_level.go
index 938b90dcf00..cb3e8d317ae 100644
--- a/internal/gatewayapi/conformance/support_level.go
+++ b/internal/gatewayapi/conformance/support_level.go
@@ -26,10 +26,18 @@ const (
)
// ExtendedFeatures is a list of supported Gateway-API features that are considered Extended.
-var ExtendedFeatures = sets.New[features.SupportedFeature]().
- Insert(features.GatewayExtendedFeatures.UnsortedList()...).
- Insert(features.HTTPRouteExtendedFeatures.UnsortedList()...).
- Insert(features.MeshExtendedFeatures.UnsortedList()...)
+var ExtendedFeatures = sets.New[features.FeatureName]()
+
+func init() {
+ featureLists := sets.New[features.Feature]().
+ Insert(features.GatewayExtendedFeatures.UnsortedList()...).
+ Insert(features.HTTPRouteExtendedFeatures.UnsortedList()...).
+ Insert(features.MeshExtendedFeatures.UnsortedList()...)
+
+ for _, feature := range featureLists.UnsortedList() {
+ ExtendedFeatures.Insert(feature.Name)
+ }
+}
// GetTestSupportLevel returns the SupportLevel for a conformance test.
// The support level is determined by the highest support level of the features.
@@ -44,7 +52,7 @@ func GetTestSupportLevel(test suite.ConformanceTest) SupportLevel {
}
// GetFeatureSupportLevel returns the SupportLevel for a feature.
-func GetFeatureSupportLevel(feature features.SupportedFeature) SupportLevel {
+func GetFeatureSupportLevel(feature features.FeatureName) SupportLevel {
supportLevel := Core
if ExtendedFeatures.Has(feature) {
diff --git a/internal/gatewayapi/contexts.go b/internal/gatewayapi/contexts.go
index 6ecb2cf7318..7bcf321d3a2 100644
--- a/internal/gatewayapi/contexts.go
+++ b/internal/gatewayapi/contexts.go
@@ -16,6 +16,7 @@ import (
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
)
// GatewayContext wraps a Gateway and provides helper methods for
@@ -29,7 +30,7 @@ type GatewayContext struct {
// ResetListeners resets the listener statuses and re-generates the GatewayContext
// ListenerContexts from the Gateway spec.
-func (g *GatewayContext) ResetListeners(resource *Resources) {
+func (g *GatewayContext) ResetListeners(resource *resource.Resources) {
numListeners := len(g.Spec.Listeners)
g.Status.Listeners = make([]gwapiv1.ListenerStatus, numListeners)
g.listeners = make([]*ListenerContext, numListeners)
@@ -46,7 +47,7 @@ func (g *GatewayContext) ResetListeners(resource *Resources) {
g.attachEnvoyProxy(resource)
}
-func (g *GatewayContext) attachEnvoyProxy(resources *Resources) {
+func (g *GatewayContext) attachEnvoyProxy(resources *resource.Resources) {
if g.Spec.Infrastructure != nil && g.Spec.Infrastructure.ParametersRef != nil && !IsMergeGatewaysEnabled(resources) {
ref := g.Spec.Infrastructure.ParametersRef
if string(ref.Group) == egv1a1.GroupVersion.Group && ref.Kind == egv1a1.KindEnvoyProxy {
@@ -75,7 +76,8 @@ type ListenerContext struct {
}
func (l *ListenerContext) SetSupportedKinds(kinds ...gwapiv1.RouteGroupKind) {
- l.gateway.Status.Listeners[l.listenerStatusIdx].SupportedKinds = kinds
+ l.gateway.Status.Listeners[l.listenerStatusIdx].SupportedKinds = make([]gwapiv1.RouteGroupKind, 0, len(kinds))
+ l.gateway.Status.Listeners[l.listenerStatusIdx].SupportedKinds = append(l.gateway.Status.Listeners[l.listenerStatusIdx].SupportedKinds, kinds...)
}
func (l *ListenerContext) IncrementAttachedRoutes() {
@@ -210,7 +212,7 @@ func GetRouteType(route RouteContext) gwapiv1.Kind {
func GetHostnames(route RouteContext) []string {
rv := reflect.ValueOf(route).Elem()
kind := rv.FieldByName("Kind").String()
- if kind == KindTCPRoute || kind == KindUDPRoute {
+ if kind == resource.KindTCPRoute || kind == resource.KindUDPRoute {
return nil
}
@@ -236,21 +238,26 @@ func GetRouteStatus(route RouteContext) *gwapiv1.RouteStatus {
return &rs
}
-// GetRouteParentContext returns RouteParentContext by using the Route
-// objects' ParentReference.
+// GetRouteParentContext returns RouteParentContext by using the Route objects' ParentReference.
+// It creates a new RouteParentContext and add a new RouteParentStatus to the Route's Status if the ParentReference is not found.
func GetRouteParentContext(route RouteContext, forParentRef gwapiv1.ParentReference) *RouteParentContext {
rv := reflect.ValueOf(route).Elem()
pr := rv.FieldByName("ParentRefs")
+
+ // If the ParentRefs field is nil, initialize it.
if pr.IsNil() {
mm := reflect.MakeMap(reflect.TypeOf(map[gwapiv1.ParentReference]*RouteParentContext{}))
pr.Set(mm)
}
+ // If the RouteParentContext is already in the RouteContext, return it.
if p := pr.MapIndex(reflect.ValueOf(forParentRef)); p.IsValid() && !p.IsZero() {
ctx := p.Interface().(*RouteParentContext)
return ctx
}
+ // Verify that the ParentReference is present in the Route.Spec.ParentRefs.
+ // This is just a sanity check, the parentRef should always be present, otherwise it's a programming error.
var parentRef *gwapiv1.ParentReference
specParentRefs := rv.FieldByName("Spec").FieldByName("ParentRefs")
for i := 0; i < specParentRefs.Len(); i++ {
@@ -264,25 +271,19 @@ func GetRouteParentContext(route RouteContext, forParentRef gwapiv1.ParentRefere
panic("parentRef not found")
}
+ // Find the parent in the Route's Status.
routeParentStatusIdx := -1
- defaultNamespace := gwapiv1.Namespace(metav1.NamespaceDefault)
statusParents := rv.FieldByName("Status").FieldByName("Parents")
+
for i := 0; i < statusParents.Len(); i++ {
p := statusParents.Index(i).FieldByName("ParentRef").Interface().(gwapiv1.ParentReference)
- // For those non-v1 routes, their underlying type of `ParentReference` is v1 as well.
- // So we can skip upgrading these routes for simplicity.
- if forParentRef.Namespace == nil {
- forParentRef.Namespace = &defaultNamespace
- }
- if p.Namespace == nil {
- p.Namespace = &defaultNamespace
- }
- if reflect.DeepEqual(p, forParentRef) {
+ if isParentRefEqual(p, *parentRef, route.GetNamespace()) {
routeParentStatusIdx = i
break
}
}
+ // If the parent is not found in the Route's Status, create a new RouteParentStatus and add it to the Route's Status.
if routeParentStatusIdx == -1 {
rParentStatus := gwapiv1a2.RouteParentStatus{
ControllerName: gwapiv1a2.GatewayController(rv.FieldByName("GatewayControllerName").String()),
@@ -292,6 +293,7 @@ func GetRouteParentContext(route RouteContext, forParentRef gwapiv1.ParentRefere
routeParentStatusIdx = statusParents.Len() - 1
}
+ // Also add the RouteParentContext to the RouteContext.
ctx := &RouteParentContext{
ParentReference: parentRef,
routeParentStatusIdx: routeParentStatusIdx,
@@ -302,6 +304,34 @@ func GetRouteParentContext(route RouteContext, forParentRef gwapiv1.ParentRefere
return ctx
}
+func isParentRefEqual(ref1, ref2 gwapiv1.ParentReference, routeNS string) bool {
+ defaultGroup := (*gwapiv1.Group)(&gwapiv1.GroupVersion.Group)
+ if ref1.Group == nil {
+ ref1.Group = defaultGroup
+ }
+ if ref2.Group == nil {
+ ref2.Group = defaultGroup
+ }
+
+ defaultKind := gwapiv1.Kind(resource.KindGateway)
+ if ref1.Kind == nil {
+ ref1.Kind = &defaultKind
+ }
+ if ref2.Kind == nil {
+ ref2.Kind = &defaultKind
+ }
+
+ // If the parent's namespace is not set, default to the namespace of the Route.
+ defaultNS := gwapiv1.Namespace(routeNS)
+ if ref1.Namespace == nil {
+ ref1.Namespace = &defaultNS
+ }
+ if ref2.Namespace == nil {
+ ref2.Namespace = &defaultNS
+ }
+ return reflect.DeepEqual(ref1, ref2)
+}
+
// RouteParentContext wraps a ParentReference and provides helper methods for
// setting conditions and other status information on the associated
// HTTPRoute, TLSRoute etc.
diff --git a/internal/gatewayapi/contexts_test.go b/internal/gatewayapi/contexts_test.go
index b594dc92e7a..ec6bfe6e109 100644
--- a/internal/gatewayapi/contexts_test.go
+++ b/internal/gatewayapi/contexts_test.go
@@ -12,11 +12,12 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
)
func TestContexts(t *testing.T) {
- r := &Resources{
+ r := &resource.Resources{
GatewayClass: &gwapiv1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
@@ -68,7 +69,7 @@ func TestContexts(t *testing.T) {
}
func TestContextsStaleListener(t *testing.T) {
- r := &Resources{
+ r := &resource.Resources{
GatewayClass: &gwapiv1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go
index a0882b2deba..72133f83ace 100644
--- a/internal/gatewayapi/envoyextensionpolicy.go
+++ b/internal/gatewayapi/envoyextensionpolicy.go
@@ -23,6 +23,7 @@ import (
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils"
@@ -35,8 +36,8 @@ const ociURLPrefix = "oci://"
func (t *Translator) ProcessEnvoyExtensionPolicies(envoyExtensionPolicies []*egv1a1.EnvoyExtensionPolicy,
gateways []*GatewayContext,
routes []RouteContext,
- resources *Resources,
- xdsIR XdsIRMap,
+ resources *resource.Resources,
+ xdsIR resource.XdsIRMap,
) []*egv1a1.EnvoyExtensionPolicy {
var res []*egv1a1.EnvoyExtensionPolicy
@@ -76,7 +77,7 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(envoyExtensionPolicies []*egv
policyName := utils.NamespacedName(currPolicy)
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes)
for _, currTarget := range targetRefs {
- if currTarget.Kind != KindGateway {
+ if currTarget.Kind != resource.KindGateway {
policy, found := handledPolicies[policyName]
if !found {
policy = currPolicy.DeepCopy()
@@ -96,7 +97,7 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(envoyExtensionPolicies []*egv
parentRefs := GetParentReferences(route)
ancestorRefs := make([]gwapiv1a2.ParentReference, 0, len(parentRefs))
for _, p := range parentRefs {
- if p.Kind == nil || *p.Kind == KindGateway {
+ if p.Kind == nil || *p.Kind == resource.KindGateway {
namespace := route.GetNamespace()
if p.Namespace != nil {
namespace = string(*p.Namespace)
@@ -150,7 +151,7 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(envoyExtensionPolicies []*egv
policyName := utils.NamespacedName(currPolicy)
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways)
for _, currTarget := range targetRefs {
- if currTarget.Kind == KindGateway {
+ if currTarget.Kind == resource.KindGateway {
policy, found := handledPolicies[policyName]
if !found {
policy = currPolicy.DeepCopy()
@@ -222,12 +223,10 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(envoyExtensionPolicies []*egv
}
func resolveEEPolicyGatewayTargetRef(policy *egv1a1.EnvoyExtensionPolicy, target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName, gateways map[types.NamespacedName]*policyGatewayTargetContext) (*GatewayContext, *status.PolicyResolveError) {
- targetNs := policy.Namespace
-
// Check if the gateway exists
key := types.NamespacedName{
Name: string(target.Name),
- Namespace: targetNs,
+ Namespace: policy.Namespace,
}
gateway, ok := gateways[key]
@@ -236,17 +235,6 @@ func resolveEEPolicyGatewayTargetRef(policy *egv1a1.EnvoyExtensionPolicy, target
return nil, nil
}
- // Ensure Policy and target are in the same namespace
- if policy.Namespace != targetNs {
- message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, EnvoyExtensionPolicy can only target a resource in the same namespace.",
- policy.Namespace, targetNs)
-
- return gateway.GatewayContext, &status.PolicyResolveError{
- Reason: gwapiv1a2.PolicyReasonInvalid,
- Message: message,
- }
- }
-
// Check if another policy targeting the same Gateway exists
if gateway.attached {
message := fmt.Sprintf("Unable to target Gateway %s, another EnvoyExtensionPolicy has already attached to it",
@@ -266,13 +254,11 @@ func resolveEEPolicyGatewayTargetRef(policy *egv1a1.EnvoyExtensionPolicy, target
}
func resolveEEPolicyRouteTargetRef(policy *egv1a1.EnvoyExtensionPolicy, target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName, routes map[policyTargetRouteKey]*policyRouteTargetContext) (RouteContext, *status.PolicyResolveError) {
- targetNs := policy.Namespace
-
// Check if the route exists
key := policyTargetRouteKey{
Kind: string(target.Kind),
Name: string(target.Name),
- Namespace: targetNs,
+ Namespace: policy.Namespace,
}
route, ok := routes[key]
@@ -281,17 +267,6 @@ func resolveEEPolicyRouteTargetRef(policy *egv1a1.EnvoyExtensionPolicy, target g
return nil, nil
}
- // Ensure Policy and target are in the same namespace
- if policy.Namespace != targetNs {
- message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, EnvoyExtensionPolicy can only target a resource in the same namespace.",
- policy.Namespace, targetNs)
-
- return route.RouteContext, &status.PolicyResolveError{
- Reason: gwapiv1a2.PolicyReasonInvalid,
- Message: message,
- }
- }
-
// Check if another policy targeting the same xRoute exists
if route.attached {
message := fmt.Sprintf("Unable to target %s %s, another EnvoyExtensionPolicy has already attached to it",
@@ -313,8 +288,8 @@ func resolveEEPolicyRouteTargetRef(policy *egv1a1.EnvoyExtensionPolicy, target g
func (t *Translator) translateEnvoyExtensionPolicyForRoute(
policy *egv1a1.EnvoyExtensionPolicy,
route RouteContext,
- xdsIR XdsIRMap,
- resources *Resources,
+ xdsIR resource.XdsIRMap,
+ resources *resource.Resources,
) error {
var (
wasms []ir.Wasm
@@ -326,11 +301,6 @@ func (t *Translator) translateEnvoyExtensionPolicyForRoute(
errs = errors.Join(errs, err)
}
- // Early return if got any errors
- if errs != nil {
- return errs
- }
-
// Apply IR to all relevant routes
prefix := irRoutePrefix(route)
parentRefs := GetParentReferences(route)
@@ -352,6 +322,13 @@ func (t *Translator) translateEnvoyExtensionPolicyForRoute(
if irListener != nil {
for _, r := range irListener.Routes {
if strings.HasPrefix(r.Name, prefix) {
+ // return 500 and do not configure EnvoyExtensions in this case
+ if errs != nil {
+ r.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
+ }
+ continue
+ }
r.EnvoyExtensions = &ir.EnvoyExtensionFeatures{
ExtProcs: extProcs,
Wasms: wasms,
@@ -369,8 +346,8 @@ func (t *Translator) translateEnvoyExtensionPolicyForGateway(
policy *egv1a1.EnvoyExtensionPolicy,
target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName,
gateway *GatewayContext,
- xdsIR XdsIRMap,
- resources *Resources,
+ xdsIR resource.XdsIRMap,
+ resources *resource.Resources,
) error {
var (
extProcs []ir.ExtProc
@@ -387,11 +364,6 @@ func (t *Translator) translateEnvoyExtensionPolicyForGateway(
errs = errors.Join(errs, err)
}
- // Early return if got any errors
- if errs != nil {
- return errs
- }
-
irKey := t.getIRKey(gateway.Gateway)
// Should exist since we've validated this
x := xdsIR[irKey]
@@ -412,6 +384,14 @@ func (t *Translator) translateEnvoyExtensionPolicyForGateway(
continue
}
+ // return 500 and do not configure EnvoyExtensions in this case
+ if errs != nil {
+ r.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
+ }
+ continue
+ }
+
r.EnvoyExtensions = &ir.EnvoyExtensionFeatures{
ExtProcs: extProcs,
Wasms: wasms,
@@ -419,10 +399,10 @@ func (t *Translator) translateEnvoyExtensionPolicyForGateway(
}
}
- return nil
+ return errs
}
-func (t *Translator) buildExtProcs(policy *egv1a1.EnvoyExtensionPolicy, resources *Resources, envoyProxy *egv1a1.EnvoyProxy) ([]ir.ExtProc, error) {
+func (t *Translator) buildExtProcs(policy *egv1a1.EnvoyExtensionPolicy, resources *resource.Resources, envoyProxy *egv1a1.EnvoyProxy) ([]ir.ExtProc, error) {
var extProcIRList []ir.ExtProc
if policy == nil {
@@ -431,7 +411,7 @@ func (t *Translator) buildExtProcs(policy *egv1a1.EnvoyExtensionPolicy, resource
for idx, ep := range policy.Spec.ExtProc {
name := irConfigNameForExtProc(policy, idx)
- extProcIR, err := t.buildExtProc(name, utils.NamespacedName(policy), ep, idx, resources, envoyProxy)
+ extProcIR, err := t.buildExtProc(name, policy, ep, idx, resources, envoyProxy)
if err != nil {
return nil, err
}
@@ -442,64 +422,44 @@ func (t *Translator) buildExtProcs(policy *egv1a1.EnvoyExtensionPolicy, resource
func (t *Translator) buildExtProc(
name string,
- policyNamespacedName types.NamespacedName,
+ policy *egv1a1.EnvoyExtensionPolicy,
extProc egv1a1.ExtProc,
extProcIdx int,
- resources *Resources,
+ resources *resource.Resources,
envoyProxy *egv1a1.EnvoyProxy,
) (*ir.ExtProc, error) {
var (
- ds *ir.DestinationSetting
+ rd *ir.RouteDestination
authority string
err error
)
- var dsl []*ir.DestinationSetting
- for i := range extProc.BackendRefs {
- if err = t.validateExtServiceBackendReference(
- &extProc.BackendRefs[i].BackendObjectReference,
- policyNamespacedName.Namespace,
- egv1a1.KindEnvoyExtensionPolicy,
- resources); err != nil {
- return nil, err
- }
-
- ds, err = t.processExtServiceDestination(
- &extProc.BackendRefs[i].BackendObjectReference,
- policyNamespacedName,
- egv1a1.KindEnvoyExtensionPolicy,
- ir.GRPC,
- resources,
- envoyProxy,
- )
- if err != nil {
- return nil, err
- }
-
- dsl = append(dsl, ds)
- }
-
- rd := ir.RouteDestination{
- Name: irIndexedExtServiceDestinationName(policyNamespacedName, egv1a1.KindEnvoyExtensionPolicy, extProcIdx),
- Settings: dsl,
+ if rd, err = t.translateExtServiceBackendRefs(policy, extProc.BackendRefs, ir.GRPC, resources, envoyProxy, "extproc", extProcIdx); err != nil {
+ return nil, err
}
if extProc.BackendRefs[0].Port != nil {
authority = fmt.Sprintf(
"%s.%s:%d",
extProc.BackendRefs[0].Name,
- NamespaceDerefOr(extProc.BackendRefs[0].Namespace, policyNamespacedName.Namespace),
+ NamespaceDerefOr(extProc.BackendRefs[0].Namespace, policy.Namespace),
*extProc.BackendRefs[0].Port)
} else {
authority = fmt.Sprintf(
"%s.%s",
extProc.BackendRefs[0].Name,
- NamespaceDerefOr(extProc.BackendRefs[0].Namespace, policyNamespacedName.Namespace))
+ NamespaceDerefOr(extProc.BackendRefs[0].Namespace, policy.Namespace))
+ }
+
+ traffic, err := translateTrafficFeatures(extProc.BackendCluster.BackendSettings)
+ if err != nil {
+ return nil, err
}
extProcIR := &ir.ExtProc{
Name: name,
- Destination: rd,
+ Destination: *rd,
+ Traffic: traffic,
Authority: authority,
}
@@ -521,6 +481,10 @@ func (t *Translator) buildExtProc(
if extProc.ProcessingMode.Request.Body != nil {
extProcIR.RequestBodyProcessingMode = ptr.To(ir.ExtProcBodyProcessingMode(*extProc.ProcessingMode.Request.Body))
}
+
+ if extProc.ProcessingMode.Request.Attributes != nil {
+ extProcIR.RequestAttributes = append(extProcIR.RequestAttributes, extProc.ProcessingMode.Request.Attributes...)
+ }
}
if extProc.ProcessingMode.Response != nil {
@@ -528,6 +492,10 @@ func (t *Translator) buildExtProc(
if extProc.ProcessingMode.Response.Body != nil {
extProcIR.ResponseBodyProcessingMode = ptr.To(ir.ExtProcBodyProcessingMode(*extProc.ProcessingMode.Response.Body))
}
+
+ if extProc.ProcessingMode.Response.Attributes != nil {
+ extProcIR.ResponseAttributes = append(extProcIR.ResponseAttributes, extProc.ProcessingMode.Response.Attributes...)
+ }
}
}
@@ -543,7 +511,7 @@ func irConfigNameForExtProc(policy *egv1a1.EnvoyExtensionPolicy, index int) stri
func (t *Translator) buildWasms(
policy *egv1a1.EnvoyExtensionPolicy,
- resources *Resources,
+ resources *resource.Resources,
) ([]ir.Wasm, error) {
if t.WasmCache == nil {
return nil, fmt.Errorf("wasm cache is not initialized")
@@ -571,7 +539,7 @@ func (t *Translator) buildWasm(
config egv1a1.Wasm,
policy *egv1a1.EnvoyExtensionPolicy,
idx int,
- resources *Resources,
+ resources *resource.Resources,
) (*ir.Wasm, error) {
var (
failOpen = false
@@ -601,6 +569,8 @@ func (t *Translator) buildWasm(
switch config.Code.Type {
case egv1a1.HTTPWasmCodeSourceType:
+ var checksum string
+
// This is a sanity check, the validation should have caught this
if config.Code.HTTP == nil {
return nil, fmt.Errorf("missing HTTP field in Wasm code source")
@@ -612,7 +582,7 @@ func (t *Translator) buildWasm(
http := config.Code.HTTP
- if servingURL, _, err = t.WasmCache.Get(http.URL, wasm.GetOptions{
+ if servingURL, checksum, err = t.WasmCache.Get(http.URL, wasm.GetOptions{
Checksum: originalChecksum,
PullPolicy: pullPolicy,
ResourceName: irConfigNameForWasm(policy, idx),
@@ -624,7 +594,7 @@ func (t *Translator) buildWasm(
code = &ir.HTTPWasmCode{
ServingURL: servingURL,
OriginalURL: http.URL,
- SHA256: originalChecksum,
+ SHA256: checksum,
}
case egv1a1.ImageWasmCodeSourceType:
@@ -645,7 +615,7 @@ func (t *Translator) buildWasm(
if image.PullSecretRef != nil {
from := crossNamespaceFrom{
group: egv1a1.GroupName,
- kind: KindEnvoyExtensionPolicy,
+ kind: resource.KindEnvoyExtensionPolicy,
namespace: policy.Namespace,
}
@@ -713,6 +683,10 @@ func (t *Translator) buildWasm(
Code: code,
}
+ if config.Env != nil && len(config.Env.HostKeys) > 0 {
+ wasmIR.HostKeys = config.Env.HostKeys
+ }
+
return wasmIR, nil
}
diff --git a/internal/gatewayapi/envoypatchpolicy.go b/internal/gatewayapi/envoypatchpolicy.go
index d8558e2e579..599108012c3 100644
--- a/internal/gatewayapi/envoypatchpolicy.go
+++ b/internal/gatewayapi/envoypatchpolicy.go
@@ -14,11 +14,12 @@ import (
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
)
-func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.EnvoyPatchPolicy, xdsIR XdsIRMap) {
+func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.EnvoyPatchPolicy, xdsIR resource.XdsIRMap) {
// Sort based on priority
sort.Slice(envoyPatchPolicies, func(i, j int) bool {
return envoyPatchPolicies[i].Spec.Priority < envoyPatchPolicies[j].Spec.Priority
@@ -33,10 +34,8 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo
irKey string
)
- targetNs := policy.Namespace
-
if t.MergeGateways {
- targetKind = KindGatewayClass
+ targetKind = resource.KindGatewayClass
irKey = string(t.GatewayClassName)
ancestorRefs = []gwapiv1a2.ParentReference{
@@ -47,9 +46,9 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo
},
}
} else {
- targetKind = KindGateway
+ targetKind = resource.KindGateway
gatewayNN := types.NamespacedName{
- Namespace: targetNs,
+ Namespace: policy.Namespace,
Name: string(policy.Spec.TargetRef.Name),
}
// It must exist since the gateways have already been processed
@@ -109,32 +108,14 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo
continue
}
- // Ensure EnvoyPatchPolicy and target Gateway are in the same namespace
- if policy.Namespace != targetNs {
- message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, EnvoyPatchPolicy can only target a %s in the same namespace.",
- policy.Namespace, targetNs, targetKind)
-
- resolveErr = &status.PolicyResolveError{
- Reason: gwapiv1a2.PolicyReasonInvalid,
- Message: message,
- }
- status.SetResolveErrorForPolicyAncestors(&policy.Status,
- ancestorRefs,
- t.GatewayControllerName,
- policy.Generation,
- resolveErr,
- )
-
- continue
- }
-
// Save the patch
for _, patch := range policy.Spec.JSONPatches {
irPatch := ir.JSONPatchConfig{}
irPatch.Type = string(patch.Type)
irPatch.Name = patch.Name
- irPatch.Operation.Op = string(patch.Operation.Op)
+ irPatch.Operation.Op = ir.JSONPatchOp(patch.Operation.Op)
irPatch.Operation.Path = patch.Operation.Path
+ irPatch.Operation.JSONPath = patch.Operation.JSONPath
irPatch.Operation.From = patch.Operation.From
irPatch.Operation.Value = patch.Operation.Value
diff --git a/internal/gatewayapi/ext_service.go b/internal/gatewayapi/ext_service.go
index d0c50e5f97e..b1111ffa0f4 100644
--- a/internal/gatewayapi/ext_service.go
+++ b/internal/gatewayapi/ext_service.go
@@ -12,20 +12,73 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
+ "sigs.k8s.io/controller-runtime/pkg/client"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils"
)
-// TODO: zhaohuabing combine this function with the one in the route translator
+// translateExtServiceBackendRefs translates external service backend references to route destinations.
+func (t *Translator) translateExtServiceBackendRefs(
+ policy client.Object,
+ backendRefs []egv1a1.BackendRef,
+ protocol ir.AppProtocol,
+ resources *resource.Resources,
+ envoyProxy *egv1a1.EnvoyProxy,
+ configType string,
+ index int, // index is used to differentiate between multiple external services in the same policy
+) (*ir.RouteDestination, error) {
+ var (
+ rs *ir.RouteDestination
+ ds []*ir.DestinationSetting
+ err error
+ )
+
+ if len(backendRefs) == 0 {
+ return nil, errors.New("no backendRefs found for external service")
+ }
+
+ pnn := utils.NamespacedName(policy)
+ for _, backendRef := range backendRefs {
+ if err = t.validateExtServiceBackendReference(
+ &backendRef.BackendObjectReference,
+ policy.GetNamespace(),
+ policy.GetObjectKind().GroupVersionKind().Kind,
+ resources); err != nil {
+ return nil, err
+ }
+
+ var extServiceDest *ir.DestinationSetting
+ if extServiceDest, err = t.processExtServiceDestination(
+ &backendRef,
+ pnn,
+ policy.GetObjectKind().GroupVersionKind().Kind,
+ protocol,
+ resources,
+ envoyProxy,
+ ); err != nil {
+ return nil, err
+ }
+ ds = append(ds, extServiceDest)
+ }
+
+ rs = &ir.RouteDestination{
+ Name: irIndexedExtServiceDestinationName(pnn, policy.GetObjectKind().GroupVersionKind().Kind, configType, index),
+ Settings: ds,
+ }
+ return rs, nil
+}
+
func (t *Translator) processExtServiceDestination(
- backendRef *gwapiv1.BackendObjectReference,
+ backendRef *egv1a1.BackendRef,
policyNamespacedName types.NamespacedName,
policyKind string,
protocol ir.AppProtocol,
- resources *Resources,
+ resources *resource.Resources,
envoyProxy *egv1a1.EnvoyProxy,
) (*ir.DestinationSetting, error) {
var (
@@ -35,14 +88,14 @@ func (t *Translator) processExtServiceDestination(
backendNamespace := NamespaceDerefOr(backendRef.Namespace, policyNamespacedName.Namespace)
- switch KindDerefOr(backendRef.Kind, KindService) {
- case KindService:
- ds = t.processServiceDestinationSetting(*backendRef, backendNamespace, protocol, resources, envoyProxy)
+ switch KindDerefOr(backendRef.Kind, resource.KindService) {
+ case resource.KindService:
+ ds = t.processServiceDestinationSetting(backendRef.BackendObjectReference, backendNamespace, protocol, resources, envoyProxy)
case egv1a1.KindBackend:
if !t.BackendEnabled {
return nil, fmt.Errorf("resource %s of type Backend cannot be used since Backend is disabled in Envoy Gateway configuration", string(backendRef.Name))
}
- ds = t.processBackendDestinationSetting(*backendRef, backendNamespace, resources)
+ ds = t.processBackendDestinationSetting(backendRef.BackendObjectReference, backendNamespace, resources)
ds.Protocol = protocol
}
@@ -57,8 +110,9 @@ func (t *Translator) processExtServiceDestination(
"mixed endpointslice address type for the same backendRef is not supported")
}
- backendTLS = t.applyBackendTLSSetting(
- *backendRef,
+ var err error
+ backendTLS, err = t.applyBackendTLSSetting(
+ backendRef.BackendObjectReference,
backendNamespace,
// Gateway is not the appropriate parent reference here because the owner
// of the BackendRef is the policy, and there is no hierarchy
@@ -73,21 +127,29 @@ func (t *Translator) processExtServiceDestination(
resources,
envoyProxy,
)
+ if err != nil {
+ return nil, err
+ }
ds.TLS = backendTLS
// TODO: support weighted non-xRoute backends
ds.Weight = ptr.To(uint32(1))
-
+ if backendRef.Fallback != nil {
+ // set only the secondary priority, the backend defaults to a primary priority if unset.
+ if ptr.Deref(backendRef.Fallback, false) {
+ ds.Priority = ptr.To(uint32(1))
+ }
+ }
return ds, nil
}
-// TODO: also refer to extension type, as Wasm may also introduce destinations
-func irIndexedExtServiceDestinationName(policyNamespacedName types.NamespacedName, policyKind string, idx int) string {
+func irIndexedExtServiceDestinationName(policyNamespacedName types.NamespacedName, policyKind string, configType string, idx int) string {
return strings.ToLower(fmt.Sprintf(
- "%s/%s/%s/%d",
+ "%s/%s/%s/%s/%d",
policyKind,
policyNamespacedName.Namespace,
policyNamespacedName.Name,
+ configType,
idx))
}
diff --git a/internal/gatewayapi/extensionserverpolicy.go b/internal/gatewayapi/extensionserverpolicy.go
index 0f7c4f7524b..395a30ef33d 100644
--- a/internal/gatewayapi/extensionserverpolicy.go
+++ b/internal/gatewayapi/extensionserverpolicy.go
@@ -14,11 +14,10 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
- "k8s.io/utils/ptr"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
- gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils"
@@ -26,7 +25,7 @@ import (
func (t *Translator) ProcessExtensionServerPolicies(policies []unstructured.Unstructured,
gateways []*GatewayContext,
- xdsIR XdsIRMap,
+ xdsIR resource.XdsIRMap,
) ([]unstructured.Unstructured, error) {
res := []unstructured.Unstructured{}
@@ -57,24 +56,18 @@ func (t *Translator) ProcessExtensionServerPolicies(policies []unstructured.Unst
continue
}
for _, currTarget := range targetRefs {
- if currTarget.Kind != KindGateway {
+ if currTarget.Kind != resource.KindGateway {
errs = errors.Join(errs, fmt.Errorf("extension policy %s doesn't target a Gateway", policy.GetName()))
continue
}
// Negative statuses have already been assigned so its safe to skip
- gateway, resolveErr := resolveExtServerPolicyGatewayTargetRef(policy, currTarget, gatewayMap)
+ gateway := resolveExtServerPolicyGatewayTargetRef(policy, currTarget, gatewayMap)
if gateway == nil {
// unable to find a matching Gateway for policy
continue
}
- // Skip the gateway. Don't add anything to the policy status.
- if resolveErr != nil {
- // The targetRef part is somehow wrong, this policy can't be attached.
- continue
- }
-
// Set conditions for translation if it got any
if t.translateExtServerPolicyForGateway(policy, gateway, currTarget, xdsIR) {
// Set Accepted condition if it is unset
@@ -125,40 +118,27 @@ func policyStatusToUnstructured(policyStatus gwapiv1a2.PolicyStatus) map[string]
return ret
}
-func resolveExtServerPolicyGatewayTargetRef(policy *unstructured.Unstructured, target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName, gateways map[types.NamespacedName]*policyGatewayTargetContext) (*GatewayContext, *status.PolicyResolveError) {
- targetNs := ptr.To(gwapiv1b1.Namespace(policy.GetNamespace()))
-
+func resolveExtServerPolicyGatewayTargetRef(policy *unstructured.Unstructured, target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName, gateways map[types.NamespacedName]*policyGatewayTargetContext) *GatewayContext {
// Check if the gateway exists
key := types.NamespacedName{
Name: string(target.Name),
- Namespace: string(*targetNs),
+ Namespace: policy.GetNamespace(),
}
gateway, ok := gateways[key]
// Gateway not found
if !ok {
- return nil, nil
- }
-
- // Ensure Policy and target are in the same namespace
- if policy.GetNamespace() != string(*targetNs) {
- message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, extension server policies can only target a resource in the same namespace.",
- policy.GetNamespace(), *targetNs)
-
- return gateway.GatewayContext, &status.PolicyResolveError{
- Reason: gwapiv1a2.PolicyReasonInvalid,
- Message: message,
- }
+ return nil
}
- return gateway.GatewayContext, nil
+ return gateway.GatewayContext
}
func (t *Translator) translateExtServerPolicyForGateway(
policy *unstructured.Unstructured,
gateway *GatewayContext,
target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName,
- xdsIR XdsIRMap,
+ xdsIR resource.XdsIRMap,
) bool {
irKey := t.getIRKey(gateway.Gateway)
gwIR := xdsIR[irKey]
diff --git a/internal/gatewayapi/filters.go b/internal/gatewayapi/filters.go
index b3d2ddb4074..7e1b5f0409a 100644
--- a/internal/gatewayapi/filters.go
+++ b/internal/gatewayapi/filters.go
@@ -7,11 +7,15 @@ package gatewayapi
import (
"fmt"
+ "regexp"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/utils/ptr"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
)
@@ -27,8 +31,7 @@ type HTTPFiltersTranslator interface {
processRedirectFilter(redirect *gwapiv1.HTTPRequestRedirectFilter, filterContext *HTTPFiltersContext)
processRequestHeaderModifierFilter(headerModifier *gwapiv1.HTTPHeaderFilter, filterContext *HTTPFiltersContext)
processResponseHeaderModifierFilter(headerModifier *gwapiv1.HTTPHeaderFilter, filterContext *HTTPFiltersContext)
- processRequestMirrorFilter(filterIdx int, mirror *gwapiv1.HTTPRequestMirrorFilter, filterContext *HTTPFiltersContext, resources *Resources)
- processExtensionRefHTTPFilter(extRef *gwapiv1.LocalObjectReference, filterContext *HTTPFiltersContext, resources *Resources)
+ processRequestMirrorFilter(filterIdx int, mirror *gwapiv1.HTTPRequestMirrorFilter, filterContext *HTTPFiltersContext, resources *resource.Resources) error
processUnsupportedHTTPFilter(filterType string, filterContext *HTTPFiltersContext)
}
@@ -43,7 +46,7 @@ type HTTPFiltersContext struct {
// HTTPFilterIR contains the ir processing results.
type HTTPFilterIR struct {
- DirectResponse *ir.DirectResponse
+ DirectResponse *ir.CustomResponse
RedirectResponse *ir.Redirect
URLRewrite *ir.URLRewrite
@@ -64,14 +67,15 @@ func (t *Translator) ProcessHTTPFilters(parentRef *RouteParentContext,
route RouteContext,
filters []gwapiv1.HTTPRouteFilter,
ruleIdx int,
- resources *Resources,
-) *HTTPFiltersContext {
+ resources *resource.Resources,
+) (*HTTPFiltersContext, error) {
httpFiltersContext := &HTTPFiltersContext{
ParentRef: parentRef,
Route: route,
RuleIdx: ruleIdx,
HTTPFilterIR: &HTTPFilterIR{},
}
+ var err error
for i := range filters {
filter := filters[i]
// If an invalid filter type has been configured then skip processing any more filters
@@ -93,7 +97,7 @@ func (t *Translator) ProcessHTTPFilters(parentRef *RouteParentContext,
case gwapiv1.HTTPRouteFilterResponseHeaderModifier:
t.processResponseHeaderModifierFilter(filter.ResponseHeaderModifier, httpFiltersContext)
case gwapiv1.HTTPRouteFilterRequestMirror:
- t.processRequestMirrorFilter(i, filter.RequestMirror, httpFiltersContext, resources)
+ err = t.processRequestMirrorFilter(i, filter.RequestMirror, httpFiltersContext, resources)
case gwapiv1.HTTPRouteFilterExtensionRef:
t.processExtensionRefHTTPFilter(filter.ExtensionRef, httpFiltersContext, resources)
default:
@@ -101,21 +105,22 @@ func (t *Translator) ProcessHTTPFilters(parentRef *RouteParentContext,
}
}
- return httpFiltersContext
+ return httpFiltersContext, err
}
// ProcessGRPCFilters translates gateway api grpc filters to IRs.
func (t *Translator) ProcessGRPCFilters(parentRef *RouteParentContext,
route RouteContext,
filters []gwapiv1.GRPCRouteFilter,
- resources *Resources,
-) *HTTPFiltersContext {
+ resources *resource.Resources,
+) (*HTTPFiltersContext, error) {
httpFiltersContext := &HTTPFiltersContext{
ParentRef: parentRef,
Route: route,
HTTPFilterIR: &HTTPFilterIR{},
}
+
for i := range filters {
filter := filters[i]
// If an invalid filter type has been configured then skip processing any more filters
@@ -133,7 +138,10 @@ func (t *Translator) ProcessGRPCFilters(parentRef *RouteParentContext,
case gwapiv1.GRPCRouteFilterResponseHeaderModifier:
t.processResponseHeaderModifierFilter(filter.ResponseHeaderModifier, httpFiltersContext)
case gwapiv1.GRPCRouteFilterRequestMirror:
- t.processRequestMirrorFilter(i, filter.RequestMirror, httpFiltersContext, resources)
+ err := t.processRequestMirrorFilter(i, filter.RequestMirror, httpFiltersContext, resources)
+ if err != nil {
+ return nil, err
+ }
case gwapiv1.GRPCRouteFilterExtensionRef:
t.processExtensionRefHTTPFilter(filter.ExtensionRef, httpFiltersContext, resources)
default:
@@ -141,7 +149,40 @@ func (t *Translator) ProcessGRPCFilters(parentRef *RouteParentContext,
}
}
- return httpFiltersContext
+ return httpFiltersContext, nil
+}
+
+// Checks if the context and the rewrite both contain a core gw-api HTTP URL rewrite
+func hasMultipleCoreRewrites(rewrite *gwapiv1.HTTPURLRewriteFilter, contextRewrite *ir.URLRewrite) bool {
+ contextHasCoreRewrites := contextRewrite.Path != nil && (contextRewrite.Path.FullReplace != nil ||
+ contextRewrite.Path.PrefixMatchReplace != nil) || (contextRewrite.Host != nil && contextRewrite.Host.Name != nil)
+ rewriteHasCoreRewrites := rewrite.Hostname != nil || rewrite.Path != nil
+ return contextHasCoreRewrites && rewriteHasCoreRewrites
+}
+
+// Checks if the context and the rewrite both contain a envoy-gateway extended HTTP URL rewrite
+func hasMultipleExtensionRewrites(rewrite *egv1a1.HTTPURLRewriteFilter, contextRewrite *ir.URLRewrite) bool {
+ contextHasExtensionRewrites := (contextRewrite.Path != nil && contextRewrite.Path.RegexMatchReplace != nil) ||
+ (contextRewrite.Host != nil && (contextRewrite.Host.Header != nil || contextRewrite.Host.Backend != nil))
+
+ return contextHasExtensionRewrites && (rewrite.Hostname != nil || rewrite.Path != nil)
+}
+
+// Checks if the context and the gw-api core rewrite both contain an HTTP URL rewrite that creates a conflict (e.g. both rewrite path)
+func hasConflictingCoreAndExtensionRewrites(rewrite *gwapiv1.HTTPURLRewriteFilter, contextRewrite *ir.URLRewrite) bool {
+ contextHasExtensionPathRewrites := contextRewrite.Path != nil && contextRewrite.Path.RegexMatchReplace != nil
+ contextHasExtensionHostRewrites := contextRewrite.Host != nil && (contextRewrite.Host.Header != nil ||
+ contextRewrite.Host.Backend != nil)
+ return (rewrite.Hostname != nil && contextHasExtensionHostRewrites) || (rewrite.Path != nil && contextHasExtensionPathRewrites)
+}
+
+// Checks if the context and the envoy-gateway extended rewrite both contain an HTTP URL rewrite that creates a conflict (e.g. both rewrite path)
+func hasConflictingExtensionAndCoreRewrites(rewrite *egv1a1.HTTPURLRewriteFilter, contextRewrite *ir.URLRewrite) bool {
+ contextHasCorePathRewrites := contextRewrite.Path != nil && (contextRewrite.Path.FullReplace != nil ||
+ contextRewrite.Path.PrefixMatchReplace != nil)
+ contextHasCoreHostnameRewrites := contextRewrite.Host != nil && contextRewrite.Host.Name != nil
+
+ return (rewrite.Hostname != nil && contextHasCoreHostnameRewrites) || (rewrite.Path != nil && contextHasCorePathRewrites)
}
func (t *Translator) processURLRewriteFilter(
@@ -149,16 +190,19 @@ func (t *Translator) processURLRewriteFilter(
filterContext *HTTPFiltersContext,
) {
if filterContext.URLRewrite != nil {
- routeStatus := GetRouteStatus(filterContext.Route)
- status.SetRouteStatusCondition(routeStatus,
- filterContext.ParentRef.routeParentStatusIdx,
- filterContext.Route.GetGeneration(),
- gwapiv1.RouteConditionAccepted,
- metav1.ConditionFalse,
- gwapiv1.RouteReasonUnsupportedValue,
- "Cannot configure multiple urlRewrite filters for a single HTTPRouteRule",
- )
- return
+ if hasMultipleCoreRewrites(rewrite, filterContext.URLRewrite) ||
+ hasConflictingCoreAndExtensionRewrites(rewrite, filterContext.URLRewrite) {
+ routeStatus := GetRouteStatus(filterContext.Route)
+ status.SetRouteStatusCondition(routeStatus,
+ filterContext.ParentRef.routeParentStatusIdx,
+ filterContext.Route.GetGeneration(),
+ gwapiv1.RouteConditionAccepted,
+ metav1.ConditionFalse,
+ gwapiv1.RouteReasonUnsupportedValue,
+ "Cannot configure multiple urlRewrite filters for a single HTTPRouteRule",
+ )
+ return
+ }
}
if rewrite == nil {
@@ -181,7 +225,9 @@ func (t *Translator) processURLRewriteFilter(
return
}
redirectHost := string(*rewrite.Hostname)
- newURLRewrite.Hostname = &redirectHost
+ newURLRewrite.Host = &ir.HTTPHostModifier{
+ Name: &redirectHost,
+ }
}
if rewrite.Path != nil {
@@ -214,8 +260,10 @@ func (t *Translator) processURLRewriteFilter(
return
}
if rewrite.Path.ReplaceFullPath != nil {
- newURLRewrite.Path = &ir.HTTPPathModifier{
- FullReplace: rewrite.Path.ReplaceFullPath,
+ newURLRewrite.Path = &ir.ExtendedHTTPPathModifier{
+ HTTPPathModifier: ir.HTTPPathModifier{
+ FullReplace: rewrite.Path.ReplaceFullPath,
+ },
}
}
case gwapiv1.PrefixMatchHTTPPathModifier:
@@ -246,8 +294,10 @@ func (t *Translator) processURLRewriteFilter(
return
}
if rewrite.Path.ReplacePrefixMatch != nil {
- newURLRewrite.Path = &ir.HTTPPathModifier{
- PrefixMatchReplace: rewrite.Path.ReplacePrefixMatch,
+ newURLRewrite.Path = &ir.ExtendedHTTPPathModifier{
+ HTTPPathModifier: ir.HTTPPathModifier{
+ PrefixMatchReplace: rewrite.Path.ReplacePrefixMatch,
+ },
}
}
default:
@@ -445,7 +495,7 @@ func (t *Translator) processRequestHeaderModifierFilter(
newHeader := ir.AddHeader{
Name: headerKey,
Append: true,
- Value: addHeader.Value,
+ Value: strings.Split(addHeader.Value, ","),
}
filterContext.AddRequestHeaders = append(filterContext.AddRequestHeaders, newHeader)
@@ -500,7 +550,7 @@ func (t *Translator) processRequestHeaderModifierFilter(
newHeader := ir.AddHeader{
Name: string(setHeader.Name),
Append: false,
- Value: setHeader.Value,
+ Value: strings.Split(setHeader.Value, ","),
}
filterContext.AddRequestHeaders = append(filterContext.AddRequestHeaders, newHeader)
@@ -617,7 +667,7 @@ func (t *Translator) processResponseHeaderModifierFilter(
newHeader := ir.AddHeader{
Name: headerKey,
Append: true,
- Value: addHeader.Value,
+ Value: strings.Split(addHeader.Value, ","),
}
filterContext.AddResponseHeaders = append(filterContext.AddResponseHeaders, newHeader)
@@ -672,7 +722,7 @@ func (t *Translator) processResponseHeaderModifierFilter(
newHeader := ir.AddHeader{
Name: string(setHeader.Name),
Append: false,
- Value: setHeader.Value,
+ Value: strings.Split(setHeader.Value, ","),
}
filterContext.AddResponseHeaders = append(filterContext.AddResponseHeaders, newHeader)
@@ -730,13 +780,163 @@ func (t *Translator) processResponseHeaderModifierFilter(
}
}
-func (t *Translator) processExtensionRefHTTPFilter(extFilter *gwapiv1.LocalObjectReference, filterContext *HTTPFiltersContext, resources *Resources) {
+func (t *Translator) processExtensionRefHTTPFilter(extFilter *gwapiv1.LocalObjectReference, filterContext *HTTPFiltersContext, resources *resource.Resources) {
// Make sure the config actually exists.
if extFilter == nil {
return
}
filterNs := filterContext.Route.GetNamespace()
+
+ if string(extFilter.Kind) == egv1a1.KindHTTPRouteFilter {
+ found := false
+ for _, hrf := range resources.HTTPRouteFilters {
+ if hrf.Namespace == filterNs && hrf.Name == string(extFilter.Name) {
+ found = true
+ if hrf.Spec.URLRewrite != nil {
+
+ if filterContext.URLRewrite != nil {
+ if hasMultipleExtensionRewrites(hrf.Spec.URLRewrite, filterContext.URLRewrite) ||
+ hasConflictingExtensionAndCoreRewrites(hrf.Spec.URLRewrite, filterContext.URLRewrite) {
+ routeStatus := GetRouteStatus(filterContext.Route)
+ status.SetRouteStatusCondition(routeStatus,
+ filterContext.ParentRef.routeParentStatusIdx,
+ filterContext.Route.GetGeneration(),
+ gwapiv1.RouteConditionAccepted,
+ metav1.ConditionFalse,
+ gwapiv1.RouteReasonUnsupportedValue,
+ "Cannot configure multiple urlRewrite filters for a single HTTPRouteRule",
+ )
+ return
+ }
+ }
+
+ if hrf.Spec.URLRewrite.Path != nil {
+ if hrf.Spec.URLRewrite.Path.Type == egv1a1.RegexHTTPPathModifier {
+ if hrf.Spec.URLRewrite.Path.ReplaceRegexMatch == nil ||
+ hrf.Spec.URLRewrite.Path.ReplaceRegexMatch.Pattern == "" {
+ errMsg := "ReplaceRegexMatch Pattern must be set when rewrite path type is \"ReplaceRegexMatch\""
+ routeStatus := GetRouteStatus(filterContext.Route)
+ status.SetRouteStatusCondition(routeStatus,
+ filterContext.ParentRef.routeParentStatusIdx,
+ filterContext.Route.GetGeneration(),
+ gwapiv1.RouteConditionAccepted,
+ metav1.ConditionFalse,
+ gwapiv1.RouteReasonUnsupportedValue,
+ errMsg,
+ )
+ return
+ } else if _, err := regexp.Compile(hrf.Spec.URLRewrite.Path.ReplaceRegexMatch.Pattern); err != nil {
+ // Avoid envoy NACKs due to invalid regex.
+ // Golang's regexp is almost identical to RE2: https://pkg.go.dev/regexp/syntax
+ errMsg := "ReplaceRegexMatch must be a valid RE2 regular expression"
+ routeStatus := GetRouteStatus(filterContext.Route)
+ status.SetRouteStatusCondition(routeStatus,
+ filterContext.ParentRef.routeParentStatusIdx,
+ filterContext.Route.GetGeneration(),
+ gwapiv1.RouteConditionAccepted,
+ metav1.ConditionFalse,
+ gwapiv1.RouteReasonUnsupportedValue,
+ errMsg,
+ )
+ return
+ }
+
+ rmr := &ir.RegexMatchReplace{
+ Pattern: hrf.Spec.URLRewrite.Path.ReplaceRegexMatch.Pattern,
+ Substitution: hrf.Spec.URLRewrite.Path.ReplaceRegexMatch.Substitution,
+ }
+
+ if filterContext.HTTPFilterIR.URLRewrite != nil {
+ if filterContext.HTTPFilterIR.URLRewrite.Path == nil {
+ filterContext.HTTPFilterIR.URLRewrite.Path = &ir.ExtendedHTTPPathModifier{
+ RegexMatchReplace: rmr,
+ }
+ }
+ } else { // no url rewrite
+ filterContext.HTTPFilterIR.URLRewrite = &ir.URLRewrite{
+ Path: &ir.ExtendedHTTPPathModifier{
+ RegexMatchReplace: rmr,
+ },
+ }
+ }
+ }
+ }
+
+ if hrf.Spec.URLRewrite.Hostname != nil {
+ var hm *ir.HTTPHostModifier
+ if hrf.Spec.URLRewrite.Hostname.Type == egv1a1.HeaderHTTPHostnameModifier {
+ if hrf.Spec.URLRewrite.Hostname.Header == nil {
+ errMsg := "Header must be set when rewrite path type is \"Header\""
+ routeStatus := GetRouteStatus(filterContext.Route)
+ status.SetRouteStatusCondition(routeStatus,
+ filterContext.ParentRef.routeParentStatusIdx,
+ filterContext.Route.GetGeneration(),
+ gwapiv1.RouteConditionAccepted,
+ metav1.ConditionFalse,
+ gwapiv1.RouteReasonUnsupportedValue,
+ errMsg,
+ )
+ return
+ }
+ hm = &ir.HTTPHostModifier{
+ Header: hrf.Spec.URLRewrite.Hostname.Header,
+ }
+ } else if hrf.Spec.URLRewrite.Hostname.Type == egv1a1.BackendHTTPHostnameModifier {
+ hm = &ir.HTTPHostModifier{
+ Backend: ptr.To(true),
+ }
+ }
+
+ if filterContext.HTTPFilterIR.URLRewrite != nil {
+ if filterContext.HTTPFilterIR.URLRewrite.Host == nil {
+ filterContext.HTTPFilterIR.URLRewrite.Host = hm
+ }
+ } else { // no url rewrite
+ filterContext.HTTPFilterIR.URLRewrite = &ir.URLRewrite{
+ Host: hm,
+ }
+ }
+ }
+
+ }
+
+ if hrf.Spec.DirectResponse != nil {
+ dr := &ir.CustomResponse{}
+ if hrf.Spec.DirectResponse.Body != nil {
+ var err error
+ if dr.Body, err = getCustomResponseBody(*hrf.Spec.DirectResponse.Body, resources, filterNs); err != nil {
+ t.processInvalidHTTPFilter(string(extFilter.Kind), filterContext, err)
+ return
+ }
+ }
+
+ if hrf.Spec.DirectResponse.StatusCode != nil {
+ dr.StatusCode = ptr.To(uint32(*hrf.Spec.DirectResponse.StatusCode))
+ } else {
+ dr.StatusCode = ptr.To(uint32(200))
+ }
+
+ if hrf.Spec.DirectResponse.ContentType != nil {
+ newHeader := ir.AddHeader{
+ Name: "Content-Type",
+ Value: []string{*hrf.Spec.DirectResponse.ContentType},
+ }
+ filterContext.AddResponseHeaders = append(filterContext.AddResponseHeaders, newHeader)
+ }
+
+ filterContext.HTTPFilterIR.DirectResponse = dr
+ }
+ }
+ }
+ if !found {
+ errMsg := fmt.Sprintf("Unable to translate HTTPRouteFilter: %s/%s", filterNs,
+ extFilter.Name)
+ t.processUnresolvedHTTPFilter(errMsg, filterContext)
+ }
+ return
+ }
+
// This list of resources will be empty unless an extension is loaded (and introduces resources)
for _, res := range resources.ExtensionRefFilters {
if res.GetKind() == string(extFilter.Kind) && res.GetName() == string(extFilter.Name) && res.GetNamespace() == filterNs {
@@ -752,9 +952,9 @@ func (t *Translator) processExtensionRefHTTPFilter(extFilter *gwapiv1.LocalObjec
}
group := apiVers[:idx]
if group == string(extFilter.Group) {
- resource := res // Capture loop variable
+ res := res // Capture loop variable
filterContext.ExtensionRefs = append(filterContext.ExtensionRefs, &ir.UnstructuredRef{
- Object: &resource,
+ Object: &res,
})
return
}
@@ -771,11 +971,11 @@ func (t *Translator) processRequestMirrorFilter(
filterIdx int,
mirrorFilter *gwapiv1.HTTPRequestMirrorFilter,
filterContext *HTTPFiltersContext,
- resources *Resources,
-) {
+ resources *resource.Resources,
+) error {
// Make sure the config actually exists
if mirrorFilter == nil {
- return
+ return nil
}
mirrorBackend := mirrorFilter.BackendRef
@@ -792,18 +992,23 @@ func (t *Translator) processRequestMirrorFilter(
// This sets the status on the HTTPRoute, should the usage be changed so that the status message reflects that the backendRef is from the filter?
filterNs := filterContext.Route.GetNamespace()
serviceNamespace := NamespaceDerefOr(mirrorBackend.Namespace, filterNs)
- if !t.validateBackendRef(mirrorBackendRef, filterContext.ParentRef, filterContext.Route,
- resources, serviceNamespace, KindHTTPRoute) {
- return
+ err := t.validateBackendRef(mirrorBackendRef, filterContext.ParentRef, filterContext.Route,
+ resources, serviceNamespace, resource.KindHTTPRoute)
+ if err != nil {
+ return err
}
- ds := t.processDestination(mirrorBackendRef, filterContext.ParentRef, filterContext.Route, resources)
+ ds, err := t.processDestination(mirrorBackendRef, filterContext.ParentRef, filterContext.Route, resources)
+ if err != nil {
+ return err
+ }
newMirror := &ir.RouteDestination{
Name: fmt.Sprintf("%s-mirror-%d", irRouteDestinationName(filterContext.Route, filterContext.RuleIdx), filterIdx),
Settings: []*ir.DestinationSetting{ds},
}
filterContext.Mirrors = append(filterContext.Mirrors, newMirror)
+ return nil
}
func (t *Translator) processUnresolvedHTTPFilter(errMsg string, filterContext *HTTPFiltersContext) {
@@ -824,8 +1029,8 @@ func (t *Translator) processUnresolvedHTTPFilter(errMsg string, filterContext *H
gwapiv1.RouteReasonUnsupportedValue,
errMsg,
)
- filterContext.DirectResponse = &ir.DirectResponse{
- StatusCode: 500,
+ filterContext.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
}
}
@@ -840,8 +1045,8 @@ func (t *Translator) processUnsupportedHTTPFilter(filterType string, filterConte
gwapiv1.RouteReasonUnsupportedValue,
errMsg,
)
- filterContext.DirectResponse = &ir.DirectResponse{
- StatusCode: 500,
+ filterContext.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
}
}
@@ -856,7 +1061,7 @@ func (t *Translator) processInvalidHTTPFilter(filterType string, filterContext *
gwapiv1.RouteReasonUnsupportedValue,
errMsg,
)
- filterContext.DirectResponse = &ir.DirectResponse{
- StatusCode: 500,
+ filterContext.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
}
}
diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go
index 22c81032ebb..2626e1b4be3 100644
--- a/internal/gatewayapi/helpers.go
+++ b/internal/gatewayapi/helpers.go
@@ -24,6 +24,7 @@ import (
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils"
)
@@ -81,9 +82,11 @@ var (
PathMatchTypeDerefOr = ptr.Deref[gwapiv1.PathMatchType]
GRPCMethodMatchTypeDerefOr = ptr.Deref[gwapiv1.GRPCMethodMatchType]
HeaderMatchTypeDerefOr = ptr.Deref[gwapiv1.HeaderMatchType]
+ GRPCHeaderMatchTypeDerefOr = ptr.Deref[gwapiv1.GRPCHeaderMatchType]
QueryParamMatchTypeDerefOr = ptr.Deref[gwapiv1.QueryParamMatchType]
)
+// Deprecated: use k8s.io/utils/ptr ptr.Deref instead
func NamespaceDerefOr(namespace *gwapiv1.Namespace, defaultNamespace string) string {
if namespace != nil && *namespace != "" {
return string(*namespace)
@@ -114,7 +117,7 @@ func IsRefToGateway(routeNamespace gwapiv1.Namespace, parentRef gwapiv1.ParentRe
return false
}
- if parentRef.Kind != nil && string(*parentRef.Kind) != KindGateway {
+ if parentRef.Kind != nil && string(*parentRef.Kind) != resource.KindGateway {
return false
}
@@ -178,6 +181,9 @@ func ValidateHTTPRouteFilter(filter *gwapiv1.HTTPRouteFilter, extGKs ...schema.G
switch {
case filter.ExtensionRef == nil:
return errors.New("extensionRef field must be specified for an extended filter")
+ case string(filter.ExtensionRef.Group) == egv1a1.GroupVersion.Group &&
+ string(filter.ExtensionRef.Kind) == egv1a1.KindHTTPRouteFilter:
+ return nil
default:
for _, gk := range extGKs {
if filter.ExtensionRef.Group == gwapiv1.Group(gk.Group) &&
@@ -262,12 +268,12 @@ func servicePortToContainerPort(servicePort int32, envoyProxy *egv1a1.EnvoyProxy
return servicePort
}
-// computeHosts returns a list of the intersecting hostnames between the route
-// and the listener.
-func computeHosts(routeHostnames []string, listenerHostname *gwapiv1.Hostname) []string {
+// computeHosts returns a list of intersecting listener hostnames and route hostnames
+// that don't intersect with other listener hostnames.
+func computeHosts(routeHostnames []string, listenerContext *ListenerContext) []string {
var listenerHostnameVal string
- if listenerHostname != nil {
- listenerHostnameVal = string(*listenerHostname)
+ if listenerContext != nil && listenerContext.Hostname != nil {
+ listenerHostnameVal = string(*listenerContext.Hostname)
}
// No route hostnames specified: use the listener hostname if specified,
@@ -280,8 +286,9 @@ func computeHosts(routeHostnames []string, listenerHostname *gwapiv1.Hostname) [
return []string{"*"}
}
- var hostnames []string
+ hostnamesSet := sets.NewString()
+ // Find intersecting hostnames
for i := range routeHostnames {
routeHostname := routeHostnames[i]
@@ -290,28 +297,47 @@ func computeHosts(routeHostnames []string, listenerHostname *gwapiv1.Hostname) [
switch {
// No listener hostname: use the route hostname.
case len(listenerHostnameVal) == 0:
- hostnames = append(hostnames, routeHostname)
+ hostnamesSet.Insert(routeHostname)
// Listener hostname matches the route hostname: use it.
case listenerHostnameVal == routeHostname:
- hostnames = append(hostnames, routeHostname)
+ hostnamesSet.Insert(routeHostname)
// Listener has a wildcard hostname: check if the route hostname matches.
case strings.HasPrefix(listenerHostnameVal, "*"):
if hostnameMatchesWildcardHostname(routeHostname, listenerHostnameVal) {
- hostnames = append(hostnames, routeHostname)
+ hostnamesSet.Insert(routeHostname)
}
// Route has a wildcard hostname: check if the listener hostname matches.
case strings.HasPrefix(routeHostname, "*"):
if hostnameMatchesWildcardHostname(listenerHostnameVal, routeHostname) {
- hostnames = append(hostnames, listenerHostnameVal)
+ hostnamesSet.Insert(listenerHostnameVal)
}
}
}
- return hostnames
+ // Filter out route hostnames that intersect with other listener hostnames
+ var listeners []*ListenerContext
+ if listenerContext != nil && listenerContext.gateway != nil {
+ listeners = listenerContext.gateway.listeners
+ }
+
+ for _, listener := range listeners {
+ if listenerContext == listener {
+ continue
+ }
+ if listenerContext != nil && listenerContext.Port != listener.Port {
+ continue
+ }
+ if listener.Hostname == nil {
+ continue
+ }
+ hostnamesSet.Delete(string(*listener.Hostname))
+ }
+
+ return hostnamesSet.List()
}
// hostnameMatchesWildcardHostname returns true if hostname has the non-wildcard
@@ -396,6 +422,7 @@ func irRouteDestinationName(route RouteContext, ruleIdx int) string {
return fmt.Sprintf("%srule/%d", irRoutePrefix(route), ruleIdx)
}
+// irTLSConfigs produces a defaulted IR TLSConfig
func irTLSConfigs(tlsSecrets ...*corev1.Secret) *ir.TLSConfig {
if len(tlsSecrets) == 0 {
return nil
@@ -411,6 +438,21 @@ func irTLSConfigs(tlsSecrets ...*corev1.Secret) *ir.TLSConfig {
PrivateKey: tlsSecret.Data[corev1.TLSPrivateKeyKey],
}
}
+
+ return tlsListenerConfigs
+}
+
+// irTLSConfigsForTCPListener creates an IR TLSConfig with defaults appropriate
+// for TCP/TLS routes, e.g. disabling ALPN
+func irTLSConfigsForTCPListener(tlsSecrets ...*corev1.Secret) *ir.TLSConfig {
+ tlsListenerConfigs := irTLSConfigs(tlsSecrets...)
+
+ // Envoy Gateway disables ALPN by default for non-HTTPS listeners
+ // by setting an empty slice instead of a nil slice
+ if tlsListenerConfigs != nil {
+ tlsListenerConfigs.ALPNProtocols = []string{}
+ }
+
return tlsListenerConfigs
}
@@ -422,7 +464,7 @@ func irTLSCACertName(namespace, name string) string {
return fmt.Sprintf("%s/%s/%s", namespace, name, caCertKey)
}
-func IsMergeGatewaysEnabled(resources *Resources) bool {
+func IsMergeGatewaysEnabled(resources *resource.Resources) bool {
return resources.EnvoyProxyForGatewayClass != nil && resources.EnvoyProxyForGatewayClass.Spec.MergeGateways != nil && *resources.EnvoyProxyForGatewayClass.Spec.MergeGateways
}
@@ -438,7 +480,7 @@ func protocolSliceToStringSlice(protocols []gwapiv1.ProtocolType) []string {
func getAncestorRefForPolicy(gatewayNN types.NamespacedName, sectionName *gwapiv1a2.SectionName) gwapiv1a2.ParentReference {
return gwapiv1a2.ParentReference{
Group: GroupPtr(gwapiv1.GroupName),
- Kind: KindPtr(KindGateway),
+ Kind: KindPtr(resource.KindGateway),
Namespace: NamespacePtr(gatewayNN.Namespace),
Name: gwapiv1.ObjectName(gatewayNN.Name),
SectionName: sectionName,
@@ -560,3 +602,64 @@ func getPolicyTargetRefs[T client.Object](policy egv1a1.PolicyTargetReferences,
return ret
}
+
+// Sets *target to value if and only if *target is nil
+func setIfNil[T any](target **T, value *T) {
+ if *target == nil {
+ *target = value
+ }
+}
+
+// getServiceIPFamily returns the IP family configuration from a Kubernetes Service
+// following the dual-stack service configuration scenarios:
+// https://kubernetes.io/docs/concepts/services-networking/dual-stack/#dual-stack-service-configuration-scenarios
+//
+// The IP family is determined in the following order:
+// 1. Service.Spec.IPFamilyPolicy == RequireDualStack -> DualStack
+// 2. Service.Spec.IPFamilies length > 1 -> DualStack
+// 3. Service.Spec.IPFamilies[0] -> IPv4 or IPv6
+// 4. nil if not specified
+func getServiceIPFamily(service *corev1.Service) *egv1a1.IPFamily {
+ if service == nil {
+ return nil
+ }
+
+ // If ipFamilyPolicy is RequireDualStack, return DualStack
+ if service.Spec.IPFamilyPolicy != nil &&
+ *service.Spec.IPFamilyPolicy == corev1.IPFamilyPolicyRequireDualStack {
+ return ptr.To(egv1a1.DualStack)
+ }
+
+ // Check ipFamilies array
+ if len(service.Spec.IPFamilies) > 0 {
+ if len(service.Spec.IPFamilies) > 1 {
+ return ptr.To(egv1a1.DualStack)
+ }
+ switch service.Spec.IPFamilies[0] {
+ case corev1.IPv4Protocol:
+ return ptr.To(egv1a1.IPv4)
+ case corev1.IPv6Protocol:
+ return ptr.To(egv1a1.IPv6)
+ }
+ }
+
+ return nil
+}
+
+// getEnvoyIPFamily returns the IPFamily configuration from EnvoyProxy
+func getEnvoyIPFamily(envoyProxy *egv1a1.EnvoyProxy) *egv1a1.IPFamily {
+ if envoyProxy == nil || envoyProxy.Spec.IPFamily == nil {
+ return nil
+ }
+
+ switch *envoyProxy.Spec.IPFamily {
+ case egv1a1.IPv4:
+ return ptr.To(egv1a1.IPv4)
+ case egv1a1.IPv6:
+ return ptr.To(egv1a1.IPv6)
+ case egv1a1.DualStack:
+ return ptr.To(egv1a1.DualStack)
+ default:
+ return nil
+ }
+}
diff --git a/internal/gatewayapi/helpers_test.go b/internal/gatewayapi/helpers_test.go
index a6469715f4d..6403279a5a9 100644
--- a/internal/gatewayapi/helpers_test.go
+++ b/internal/gatewayapi/helpers_test.go
@@ -15,6 +15,7 @@ import (
"testing"
"github.com/stretchr/testify/require"
+ corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
@@ -97,7 +98,6 @@ func TestValidateGRPCFilterRef(t *testing.T) {
},
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := ValidateGRPCRouteFilter(tc.filter, schema.GroupKind{Group: "example.io", Kind: "Foo"})
if tc.expected {
@@ -189,7 +189,6 @@ func TestValidateHTTPFilterRef(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := ValidateHTTPRouteFilter(tc.filter, schema.GroupKind{Group: "example.io", Kind: "Foo"})
if tc.expected {
@@ -479,7 +478,6 @@ func TestGetPolicyTargetRefs(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
results := getPolicyTargetRefs(tc.policy, tc.targets)
require.ElementsMatch(t, results, tc.results)
@@ -554,3 +552,67 @@ func TestIsRefToGateway(t *testing.T) {
})
}
}
+
+func TestGetServiceIPFamily(t *testing.T) {
+ testCases := []struct {
+ name string
+ service *corev1.Service
+ expected *egv1a1.IPFamily
+ }{
+ {
+ name: "nil service",
+ service: nil,
+ expected: nil,
+ },
+ {
+ name: "require dual stack",
+ service: &corev1.Service{
+ Spec: corev1.ServiceSpec{
+ IPFamilyPolicy: ptr.To(corev1.IPFamilyPolicyRequireDualStack),
+ },
+ },
+ expected: ptr.To(egv1a1.DualStack),
+ },
+ {
+ name: "multiple ip families",
+ service: &corev1.Service{
+ Spec: corev1.ServiceSpec{
+ IPFamilies: []corev1.IPFamily{corev1.IPv4Protocol, corev1.IPv6Protocol},
+ },
+ },
+ expected: ptr.To(egv1a1.DualStack),
+ },
+ {
+ name: "ipv4 only",
+ service: &corev1.Service{
+ Spec: corev1.ServiceSpec{
+ IPFamilies: []corev1.IPFamily{corev1.IPv4Protocol},
+ },
+ },
+ expected: ptr.To(egv1a1.IPv4),
+ },
+ {
+ name: "ipv6 only",
+ service: &corev1.Service{
+ Spec: corev1.ServiceSpec{
+ IPFamilies: []corev1.IPFamily{corev1.IPv6Protocol},
+ },
+ },
+ expected: ptr.To(egv1a1.IPv6),
+ },
+ {
+ name: "no ip family specified",
+ service: &corev1.Service{
+ Spec: corev1.ServiceSpec{},
+ },
+ expected: nil,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ result := getServiceIPFamily(tc.service)
+ require.Equal(t, tc.expected, result)
+ })
+ }
+}
diff --git a/internal/gatewayapi/helpers_v1alpha2.go b/internal/gatewayapi/helpers_v1alpha2.go
deleted file mode 100644
index 3b1dffde66f..00000000000
--- a/internal/gatewayapi/helpers_v1alpha2.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright Envoy Gateway Authors
-// SPDX-License-Identifier: Apache-2.0
-// The full text of the Apache license is available in the LICENSE file at
-// the root of the repo.
-
-// This file contains code derived from Contour,
-// https://github.com/projectcontour/contour
-// and is provided here subject to the following:
-// Copyright Project Contour Authors
-// SPDX-License-Identifier: Apache-2.0
-
-package gatewayapi
-
-import (
- gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
- gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
-)
-
-// TODO: [gwapiv1a2-gwapiv1]
-// This file can be removed once all routes graduates to gwapiv1.
-
-// UpgradeBackendRef converts gwapiv1a2.BackendRef to gwapiv1.BackendRef
-func UpgradeBackendRef(old gwapiv1a2.BackendRef) gwapiv1.BackendRef {
- upgraded := gwapiv1.BackendRef{}
-
- if old.Group != nil {
- upgraded.Group = GroupPtr(string(*old.Group))
- }
-
- if old.Kind != nil {
- upgraded.Kind = KindPtr(string(*old.Kind))
- }
-
- if old.Namespace != nil {
- upgraded.Namespace = NamespacePtr(string(*old.Namespace))
- }
-
- upgraded.Name = old.Name
-
- if old.Port != nil {
- upgraded.Port = PortNumPtr(int32(*old.Port))
- }
-
- return upgraded
-}
diff --git a/internal/gatewayapi/http.go b/internal/gatewayapi/http.go
new file mode 100644
index 00000000000..e54b3f761d7
--- /dev/null
+++ b/internal/gatewayapi/http.go
@@ -0,0 +1,76 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package gatewayapi
+
+import (
+ "errors"
+ "fmt"
+
+ "k8s.io/utils/ptr"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/ir"
+)
+
+const (
+ MinHTTP2InitialStreamWindowSize = 65535 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size
+ MaxHTTP2InitialStreamWindowSize = 2147483647 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size
+ MinHTTP2InitialConnectionWindowSize = MinHTTP2InitialStreamWindowSize
+ MaxHTTP2InitialConnectionWindowSize = MaxHTTP2InitialStreamWindowSize
+)
+
+func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Settings, error) {
+ if http2Settings == nil {
+ return nil, nil
+ }
+ var (
+ http2 = &ir.HTTP2Settings{}
+ errs error
+ )
+
+ if http2Settings.InitialStreamWindowSize != nil {
+ initialStreamWindowSize, ok := http2Settings.InitialStreamWindowSize.AsInt64()
+ switch {
+ case !ok:
+ errs = errors.Join(errs, fmt.Errorf("invalid InitialStreamWindowSize value %s", http2Settings.InitialStreamWindowSize.String()))
+ case initialStreamWindowSize < MinHTTP2InitialStreamWindowSize || initialStreamWindowSize > MaxHTTP2InitialStreamWindowSize:
+ errs = errors.Join(errs, fmt.Errorf("InitialStreamWindowSize value %s is out of range, must be between %d and %d",
+ http2Settings.InitialStreamWindowSize.String(),
+ MinHTTP2InitialStreamWindowSize,
+ MaxHTTP2InitialStreamWindowSize))
+ default:
+ http2.InitialStreamWindowSize = ptr.To(uint32(initialStreamWindowSize))
+ }
+ }
+
+ if http2Settings.InitialConnectionWindowSize != nil {
+ initialConnectionWindowSize, ok := http2Settings.InitialConnectionWindowSize.AsInt64()
+ switch {
+ case !ok:
+ errs = errors.Join(errs, fmt.Errorf("invalid InitialConnectionWindowSize value %s", http2Settings.InitialConnectionWindowSize.String()))
+ case initialConnectionWindowSize < MinHTTP2InitialConnectionWindowSize || initialConnectionWindowSize > MaxHTTP2InitialConnectionWindowSize:
+ errs = errors.Join(errs, fmt.Errorf("InitialConnectionWindowSize value %s is out of range, must be between %d and %d",
+ http2Settings.InitialConnectionWindowSize.String(),
+ MinHTTP2InitialConnectionWindowSize,
+ MaxHTTP2InitialConnectionWindowSize))
+ default:
+ http2.InitialConnectionWindowSize = ptr.To(uint32(initialConnectionWindowSize))
+ }
+ }
+
+ http2.MaxConcurrentStreams = http2Settings.MaxConcurrentStreams
+
+ if http2Settings.OnInvalidMessage != nil {
+ switch *http2Settings.OnInvalidMessage {
+ case egv1a1.InvalidMessageActionTerminateStream:
+ http2.ResetStreamOnError = ptr.To(true)
+ case egv1a1.InvalidMessageActionTerminateConnection:
+ http2.ResetStreamOnError = ptr.To(false)
+ }
+ }
+
+ return http2, errs
+}
diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go
index adbd302b957..75739609609 100644
--- a/internal/gatewayapi/listener.go
+++ b/internal/gatewayapi/listener.go
@@ -17,19 +17,21 @@ import (
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils"
"github.com/envoyproxy/gateway/internal/utils/naming"
+ "github.com/envoyproxy/gateway/internal/utils/net"
)
var _ ListenersTranslator = (*Translator)(nil)
type ListenersTranslator interface {
- ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap, infraIR InfraIRMap, resources *Resources)
+ ProcessListeners(gateways []*GatewayContext, xdsIR resource.XdsIRMap, infraIR resource.InfraIRMap, resources *resource.Resources)
}
-func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap, infraIR InfraIRMap, resources *Resources) {
+func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR resource.XdsIRMap, infraIR resource.InfraIRMap, resources *resource.Resources) {
// Infra IR proxy ports must be unique.
foundPorts := make(map[string][]*protocolPort)
t.validateConflictedLayer7Listeners(gateways)
@@ -57,22 +59,23 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap
if listener.TLS != nil {
switch *listener.TLS.Mode {
case gwapiv1.TLSModePassthrough:
- t.validateAllowedRoutes(listener, KindTLSRoute)
+ t.validateAllowedRoutes(listener, resource.KindTLSRoute)
case gwapiv1.TLSModeTerminate:
- t.validateAllowedRoutes(listener, KindTCPRoute)
+ t.validateAllowedRoutes(listener, resource.KindTCPRoute)
default:
- t.validateAllowedRoutes(listener, KindTCPRoute, KindTLSRoute)
+ t.validateAllowedRoutes(listener, resource.KindTCPRoute, resource.KindTLSRoute)
}
} else {
- t.validateAllowedRoutes(listener, KindTCPRoute, KindTLSRoute)
+ t.validateAllowedRoutes(listener, resource.KindTCPRoute, resource.KindTLSRoute)
}
case gwapiv1.HTTPProtocolType, gwapiv1.HTTPSProtocolType:
- t.validateAllowedRoutes(listener, KindHTTPRoute, KindGRPCRoute)
+ t.validateAllowedRoutes(listener, resource.KindHTTPRoute, resource.KindGRPCRoute)
case gwapiv1.TCPProtocolType:
- t.validateAllowedRoutes(listener, KindTCPRoute)
+ t.validateAllowedRoutes(listener, resource.KindTCPRoute)
case gwapiv1.UDPProtocolType:
- t.validateAllowedRoutes(listener, KindUDPRoute)
+ t.validateAllowedRoutes(listener, resource.KindUDPRoute)
default:
+ listener.SetSupportedKinds()
status.SetGatewayListenerStatusCondition(listener.gateway.Gateway,
listener.listenerStatusIdx,
gwapiv1.ListenerConditionAccepted,
@@ -97,6 +100,13 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap
if !isReady {
continue
}
+
+ address := net.IPv4ListenerAddress
+ ipFamily := getEnvoyIPFamily(gateway.envoyProxy)
+ if ipFamily != nil && (*ipFamily == egv1a1.IPv6 || *ipFamily == egv1a1.DualStack) {
+ address = net.IPv6ListenerAddress
+ }
+
// Add the listener to the Xds IR
servicePort := &protocolPort{protocol: listener.Protocol, port: int32(listener.Port)}
containerPort := servicePortToContainerPort(int32(listener.Port), gateway.envoyProxy)
@@ -105,9 +115,10 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap
irListener := &ir.HTTPListener{
CoreListenerDetails: ir.CoreListenerDetails{
Name: irListenerName(listener),
- Address: "0.0.0.0",
+ Address: address,
Port: uint32(containerPort),
Metadata: buildListenerMetadata(listener, gateway),
+ IPFamily: ipFamily,
},
TLS: irTLSConfigs(listener.tlsSecrets...),
Path: ir.PathSettings{
@@ -127,23 +138,24 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap
case gwapiv1.TCPProtocolType, gwapiv1.TLSProtocolType:
irListener := &ir.TCPListener{
CoreListenerDetails: ir.CoreListenerDetails{
- Name: irListenerName(listener),
- Address: "0.0.0.0",
- Port: uint32(containerPort),
+ Name: irListenerName(listener),
+ Address: address,
+ Port: uint32(containerPort),
+ IPFamily: ipFamily,
},
// Gateway is processed firstly, then ClientTrafficPolicy, then xRoute.
// TLS field should be added to TCPListener as ClientTrafficPolicy will affect
// Listener TLS. Then TCPRoute whose TLS should be configured as Terminate just
// refers to the Listener TLS.
- TLS: irTLSConfigs(listener.tlsSecrets...),
+ TLS: irTLSConfigsForTCPListener(listener.tlsSecrets...),
}
xdsIR[irKey].TCP = append(xdsIR[irKey].TCP, irListener)
case gwapiv1.UDPProtocolType:
irListener := &ir.UDPListener{
CoreListenerDetails: ir.CoreListenerDetails{
Name: irListenerName(listener),
- Address: "0.0.0.0",
+ Address: address,
Port: uint32(containerPort),
},
}
@@ -170,7 +182,7 @@ func buildListenerMetadata(listener *ListenerContext, gateway *GatewayContext) *
}
}
-func (t *Translator) processProxyObservability(gwCtx *GatewayContext, xdsIR *ir.Xds, envoyProxy *egv1a1.EnvoyProxy, resources *Resources) {
+func (t *Translator) processProxyObservability(gwCtx *GatewayContext, xdsIR *ir.Xds, envoyProxy *egv1a1.EnvoyProxy, resources *resource.Resources) {
var err error
xdsIR.AccessLog, err = t.processAccessLog(envoyProxy, resources)
@@ -195,7 +207,7 @@ func (t *Translator) processProxyObservability(gwCtx *GatewayContext, xdsIR *ir.
}
}
-func (t *Translator) processInfraIRListener(listener *ListenerContext, infraIR InfraIRMap, irKey string, servicePort *protocolPort, containerPort int32) {
+func (t *Translator) processInfraIRListener(listener *ListenerContext, infraIR resource.InfraIRMap, irKey string, servicePort *protocolPort, containerPort int32) {
var proto ir.ProtocolType
switch listener.Protocol {
case gwapiv1.HTTPProtocolType:
@@ -225,7 +237,7 @@ func (t *Translator) processInfraIRListener(listener *ListenerContext, infraIR I
infraIR[irKey].Proxy.Listeners = append(infraIR[irKey].Proxy.Listeners, proxyListener)
}
-func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *Resources) (*ir.AccessLog, error) {
+func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *resource.Resources) (*ir.AccessLog, error) {
if envoyproxy == nil ||
envoyproxy.Spec.Telemetry == nil ||
envoyproxy.Spec.Telemetry.AccessLog == nil ||
@@ -239,7 +251,6 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
},
}, nil
}
-
if envoyproxy.Spec.Telemetry.AccessLog.Disable {
return nil, nil
}
@@ -247,6 +258,16 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
irAccessLog := &ir.AccessLog{}
// translate the access log configuration to the IR
for i, accessLog := range envoyproxy.Spec.Telemetry.AccessLog.Settings {
+ var accessLogType *ir.ProxyAccessLogType
+ if accessLog.Type != nil {
+ switch *accessLog.Type {
+ case egv1a1.ProxyAccessLogTypeRoute:
+ accessLogType = ptr.To(ir.ProxyAccessLogTypeRoute)
+ case egv1a1.ProxyAccessLogTypeListener:
+ accessLogType = ptr.To(ir.ProxyAccessLogTypeListener)
+ }
+ }
+
var format egv1a1.ProxyAccessLogFormat
if accessLog.Format != nil {
format = *accessLog.Format
@@ -272,6 +293,16 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
return nil, utilerrors.NewAggregate(errs)
}
+ if len(accessLog.Sinks) == 0 {
+ al := &ir.TextAccessLog{
+ Format: format.Text,
+ CELMatches: validExprs,
+ LogType: accessLogType,
+ Path: "/dev/stdout",
+ }
+ irAccessLog.Text = append(irAccessLog.Text, al)
+ }
+
for j, sink := range accessLog.Sinks {
switch sink.Type {
case egv1a1.ProxyAccessLogSinkTypeFile:
@@ -285,6 +316,7 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
Format: format.Text,
Path: sink.File.Path,
CELMatches: validExprs,
+ LogType: accessLogType,
}
irAccessLog.Text = append(irAccessLog.Text, al)
case egv1a1.ProxyAccessLogFormatTypeJSON:
@@ -297,6 +329,7 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
JSON: format.JSON,
Path: sink.File.Path,
CELMatches: validExprs,
+ LogType: accessLogType,
}
irAccessLog.JSON = append(irAccessLog.JSON, al)
}
@@ -313,7 +346,7 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
}
// TODO: how to get authority from the backendRefs?
- ds, err := t.processBackendRefs(sink.ALS.BackendRefs, envoyproxy.Namespace, resources, envoyproxy)
+ ds, traffic, err := t.processBackendRefs(sink.ALS.BackendCluster, envoyproxy.Namespace, resources, envoyproxy)
if err != nil {
return nil, err
}
@@ -321,11 +354,14 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
al := &ir.ALSAccessLog{
LogName: logName,
Destination: ir.RouteDestination{
- Name: fmt.Sprintf("accesslog_als_%d_%d", i, j), // TODO: rename this, so that we can share backend with tracing?
+ // TODO: rename this, so that we can share backend with tracing?
+ Name: fmt.Sprintf("accesslog_als_%d_%d", i, j),
Settings: ds,
},
+ Traffic: traffic,
Type: sink.ALS.Type,
CELMatches: validExprs,
+ LogType: accessLogType,
}
if al.Type == egv1a1.ALSEnvoyProxyAccessLogTypeHTTP && sink.ALS.HTTP != nil {
@@ -336,7 +372,6 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
}
al.HTTP = http
}
-
switch format.Type {
case egv1a1.ProxyAccessLogFormatTypeJSON:
al.Attributes = format.JSON
@@ -350,20 +385,22 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
continue
}
- // TODO: remove support for Host/Port in v1.2
- al := &ir.OpenTelemetryAccessLog{
- CELMatches: validExprs,
- Resources: sink.OpenTelemetry.Resources,
- }
-
// TODO: how to get authority from the backendRefs?
- ds, err := t.processBackendRefs(sink.OpenTelemetry.BackendRefs, envoyproxy.Namespace, resources, envoyproxy)
+ ds, traffic, err := t.processBackendRefs(sink.OpenTelemetry.BackendCluster, envoyproxy.Namespace, resources, envoyproxy)
if err != nil {
return nil, err
}
- al.Destination = ir.RouteDestination{
- Name: fmt.Sprintf("accesslog_otel_%d_%d", i, j), // TODO: rename this, so that we can share backend with tracing?
- Settings: ds,
+ // TODO: remove support for Host/Port in v1.2
+ al := &ir.OpenTelemetryAccessLog{
+ CELMatches: validExprs,
+ Resources: sink.OpenTelemetry.Resources,
+ Destination: ir.RouteDestination{
+ // TODO: rename this, so that we can share backend with tracing?
+ Name: fmt.Sprintf("accesslog_otel_%d_%d", i, j),
+ Settings: ds,
+ },
+ Traffic: traffic,
+ LogType: accessLogType,
}
if len(ds) == 0 {
@@ -388,11 +425,12 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
}
}
}
-
return irAccessLog, nil
}
-func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.EnvoyProxy, mergeGateways bool, resources *Resources) (*ir.Tracing, error) {
+func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.EnvoyProxy,
+ mergeGateways bool, resources *resource.Resources,
+) (*ir.Tracing, error) {
if envoyproxy == nil ||
envoyproxy.Spec.Telemetry == nil ||
envoyproxy.Spec.Telemetry.Tracing == nil {
@@ -401,7 +439,7 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo
tracing := envoyproxy.Spec.Telemetry.Tracing
// TODO: how to get authority from the backendRefs?
- ds, err := t.processBackendRefs(tracing.Provider.BackendRefs, envoyproxy.Namespace, resources, envoyproxy)
+ ds, traffic, err := t.processBackendRefs(tracing.Provider.BackendCluster, envoyproxy.Namespace, resources, envoyproxy)
if err != nil {
return nil, err
}
@@ -436,14 +474,16 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo
SamplingRate: samplingRate,
CustomTags: tracing.CustomTags,
Destination: ir.RouteDestination{
- Name: "tracing", // TODO: rename this, so that we can share backend with accesslog?
+ // TODO: rename this, so that we can share backend with accesslog?
+ Name: "tracing",
Settings: ds,
},
Provider: tracing.Provider,
+ Traffic: traffic,
}, nil
}
-func (t *Translator) processMetrics(envoyproxy *egv1a1.EnvoyProxy, resources *Resources) (*ir.Metrics, error) {
+func (t *Translator) processMetrics(envoyproxy *egv1a1.EnvoyProxy, resources *resource.Resources) (*ir.Metrics, error) {
if envoyproxy == nil ||
envoyproxy.Spec.Telemetry == nil ||
envoyproxy.Spec.Telemetry.Metrics == nil {
@@ -455,37 +495,44 @@ func (t *Translator) processMetrics(envoyproxy *egv1a1.EnvoyProxy, resources *Re
continue
}
- _, err := t.processBackendRefs(sink.OpenTelemetry.BackendRefs, envoyproxy.Namespace, resources, envoyproxy)
+ _, _, err := t.processBackendRefs(sink.OpenTelemetry.BackendCluster, envoyproxy.Namespace, resources, envoyproxy)
if err != nil {
return nil, err
}
}
return &ir.Metrics{
- EnableVirtualHostStats: envoyproxy.Spec.Telemetry.Metrics.EnableVirtualHostStats,
- EnablePerEndpointStats: envoyproxy.Spec.Telemetry.Metrics.EnablePerEndpointStats,
+ EnableVirtualHostStats: ptr.Deref(envoyproxy.Spec.Telemetry.Metrics.EnableVirtualHostStats, false),
+ EnablePerEndpointStats: ptr.Deref(envoyproxy.Spec.Telemetry.Metrics.EnablePerEndpointStats, false),
+ EnableRequestResponseSizesStats: ptr.Deref(envoyproxy.Spec.Telemetry.Metrics.EnableRequestResponseSizesStats, false),
}, nil
}
-func (t *Translator) processBackendRefs(backendRefs []egv1a1.BackendRef, namespace string, resources *Resources, envoyProxy *egv1a1.EnvoyProxy) ([]*ir.DestinationSetting, error) {
- result := make([]*ir.DestinationSetting, 0, len(backendRefs))
- for _, ref := range backendRefs {
+func (t *Translator) processBackendRefs(backendCluster egv1a1.BackendCluster, namespace string,
+ resources *resource.Resources, envoyProxy *egv1a1.EnvoyProxy,
+) ([]*ir.DestinationSetting, *ir.TrafficFeatures, error) {
+ traffic, err := translateTrafficFeatures(backendCluster.BackendSettings)
+ if err != nil {
+ return nil, nil, err
+ }
+ result := make([]*ir.DestinationSetting, 0, len(backendCluster.BackendRefs))
+ for _, ref := range backendCluster.BackendRefs {
ns := NamespaceDerefOr(ref.Namespace, namespace)
- kind := KindDerefOr(ref.Kind, KindService)
- if kind != KindService {
- return nil, errors.New("only service kind is supported for backendRefs")
+ kind := KindDerefOr(ref.Kind, resource.KindService)
+ if kind != resource.KindService {
+ return nil, nil, errors.New("only service kind is supported for backendRefs")
}
if err := validateBackendService(ref.BackendObjectReference, resources, ns, corev1.ProtocolTCP); err != nil {
- return nil, err
+ return nil, nil, err
}
ds := t.processServiceDestinationSetting(ref.BackendObjectReference, ns, ir.TCP, resources, envoyProxy)
result = append(result, ds)
}
if len(result) == 0 {
- return nil, nil
+ return nil, traffic, nil
}
- return result, nil
+ return result, traffic, nil
}
func destinationSettingFromHostAndPort(host string, port uint32) []*ir.DestinationSetting {
diff --git a/internal/gatewayapi/resource/fs.go b/internal/gatewayapi/resource/fs.go
new file mode 100644
index 00000000000..09fdcb1ab20
--- /dev/null
+++ b/internal/gatewayapi/resource/fs.go
@@ -0,0 +1,73 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package resource
+
+import (
+ "bytes"
+ "io"
+ "io/fs"
+ "time"
+
+ "github.com/envoyproxy/gateway" // nolint:goimports
+)
+
+var (
+ // gatewayCRDsFS is a virtual/mocked FS used for OpenAPI client.
+ gatewayCRDsFS = memGatewayCRDsFS{}
+
+ _ fs.FS = memGatewayCRDsFS{}
+ _ fs.ReadDirFile = memGatewayCRDsFile{}
+ _ fs.FileInfo = memGatewayCRDsFileInfo{}
+ _ fs.DirEntry = memGatewayCRDsDirEntry{}
+)
+
+// memGatewayCRDsFS is a mocked fs.FS for OpenAPI to read gatewayCRDs from.
+type memGatewayCRDsFS struct{}
+
+func (m memGatewayCRDsFS) Open(_ string) (fs.File, error) {
+ return &memGatewayCRDsFile{}, nil
+}
+
+// memGatewayCRDsFile is mocked fs.ReadDirFile for memGatewayCRDsFS.
+type memGatewayCRDsFile struct{}
+
+func (m memGatewayCRDsFile) Stat() (fs.FileInfo, error) {
+ return &memGatewayCRDsFileInfo{}, nil
+}
+
+func (m memGatewayCRDsFile) Close() error {
+ return nil
+}
+
+func (m memGatewayCRDsFile) Read(b []byte) (int, error) {
+ fi, _ := m.Stat()
+ if int64(len(b)) >= fi.Size() {
+ return bytes.NewReader(envoygateway.GatewayCRDs).Read(b)
+ }
+ return 0, io.EOF
+}
+
+func (m memGatewayCRDsFile) ReadDir(_ int) ([]fs.DirEntry, error) {
+ return []fs.DirEntry{&memGatewayCRDsDirEntry{}}, nil
+}
+
+// memGatewayCRDsDirEntry is a mocked fs.DirEntry for memGatewayCRDsFile.
+type memGatewayCRDsDirEntry struct {
+ memGatewayCRDsFileInfo
+}
+
+func (m memGatewayCRDsDirEntry) Type() fs.FileMode { return 0o444 }
+func (m memGatewayCRDsDirEntry) Info() (fs.FileInfo, error) { return &memGatewayCRDsFileInfo{}, nil }
+
+// memGatewayCRDsFileInfo is a mocked fs.FileInfo for memGatewayCRDsFile.
+type memGatewayCRDsFileInfo struct{}
+
+func (m memGatewayCRDsFileInfo) Name() string { return "gateway-crds.yaml" }
+func (m memGatewayCRDsFileInfo) Size() int64 { return int64(len(envoygateway.GatewayCRDs)) }
+func (m memGatewayCRDsFileInfo) Mode() fs.FileMode { return 0o444 }
+func (m memGatewayCRDsFileInfo) ModTime() time.Time { return time.Now() }
+func (m memGatewayCRDsFileInfo) IsDir() bool { return false }
+func (m memGatewayCRDsFileInfo) Sys() any { return nil }
diff --git a/internal/gatewayapi/resource/fs_test.go b/internal/gatewayapi/resource/fs_test.go
new file mode 100644
index 00000000000..c8742a02c84
--- /dev/null
+++ b/internal/gatewayapi/resource/fs_test.go
@@ -0,0 +1,46 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package resource
+
+import (
+ "io/fs"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "github.com/envoyproxy/gateway" // nolint:goimports
+)
+
+func TestOpenAndReadGatewayCRDsFS(t *testing.T) {
+ crds, err := gatewayCRDsFS.Open("")
+ require.NoError(t, err)
+ defer crds.Close()
+
+ buf := make([]byte, len(envoygateway.GatewayCRDs))
+ cur, err := crds.Read(buf)
+ require.NoError(t, err)
+ require.Positive(t, cur)
+}
+
+func TestReadGatewayCRDsDirFS(t *testing.T) {
+ dirEntries, err := fs.ReadDir(gatewayCRDsFS, ".")
+ require.NoError(t, err)
+ require.Len(t, dirEntries, 1)
+
+ dirEntry := dirEntries[0]
+ require.Equal(t, fs.FileMode(0o444), dirEntry.Type())
+
+ fileInfo, err := dirEntry.Info()
+ require.NoError(t, err)
+ require.Equal(t, "gateway-crds.yaml", fileInfo.Name())
+ require.NotNil(t, fileInfo.ModTime())
+ require.Nil(t, fileInfo.Sys())
+ require.False(t, fileInfo.IsDir())
+
+ fileBytes, err := fs.ReadFile(gatewayCRDsFS, fileInfo.Name())
+ require.NoError(t, err)
+ require.Equal(t, fileInfo.Size(), int64(len(fileBytes)))
+}
diff --git a/internal/gatewayapi/resource/load.go b/internal/gatewayapi/resource/load.go
new file mode 100644
index 00000000000..7c87ffb7918
--- /dev/null
+++ b/internal/gatewayapi/resource/load.go
@@ -0,0 +1,532 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package resource
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "reflect"
+
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/util/sets"
+ utilyaml "k8s.io/apimachinery/pkg/util/yaml"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+ gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
+ "sigs.k8s.io/yaml"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/envoygateway"
+ "github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/xds/bootstrap"
+)
+
+const dummyClusterIP = "1.2.3.4"
+
+// LoadResourcesFromYAMLBytes will load Resources from given Kubernetes YAML string.
+// TODO: This function should be able to process arbitrary number of resources, tracked by https://github.com/envoyproxy/gateway/issues/3207.
+func LoadResourcesFromYAMLBytes(yamlBytes []byte, addMissingResources bool) (*Resources, error) {
+ r, err := loadKubernetesYAMLToResources(yamlBytes, addMissingResources)
+ if err != nil {
+ return nil, err
+ }
+
+ return r, nil
+}
+
+// loadKubernetesYAMLToResources converts a Kubernetes YAML string into GatewayAPI Resources.
+// TODO: add support for kind:
+// - EnvoyExtensionPolicy (gateway.envoyproxy.io/v1alpha1)
+// - HTTPRouteFilter (gateway.envoyproxy.io/v1alpha1)
+// - BackendLPPolicy (gateway.networking.k8s.io/v1alpha2)
+// - BackendTLSPolicy (gateway.networking.k8s.io/v1alpha3)
+// - ReferenceGrant (gateway.networking.k8s.io/v1alpha2)
+// - TLSRoute (gateway.networking.k8s.io/v1alpha2)
+func loadKubernetesYAMLToResources(input []byte, addMissingResources bool) (*Resources, error) {
+ resources := NewResources()
+ var useDefaultNamespace bool
+ providedNamespaceMap := sets.New[string]()
+ requiredNamespaceMap := sets.New[string]()
+ combinedScheme := envoygateway.GetScheme()
+
+ if err := IterYAMLBytes(input, func(yamlByte []byte) error {
+ var obj map[string]interface{}
+ err := yaml.Unmarshal(yamlByte, &obj)
+ if err != nil {
+ return err
+ }
+
+ un := unstructured.Unstructured{Object: obj}
+ gvk := un.GroupVersionKind()
+ name, namespace := un.GetName(), un.GetNamespace()
+ if len(namespace) == 0 {
+ useDefaultNamespace = true
+ namespace = config.DefaultNamespace
+ }
+
+ // Perform local validation for gateway-api related resources only.
+ if gvk.Group == egv1a1.GroupName || gvk.Group == gwapiv1.GroupName {
+ if err = defaultValidator.Validate(yamlByte); err != nil {
+ return fmt.Errorf("local validation error: %w", err)
+ }
+ }
+
+ requiredNamespaceMap.Insert(namespace)
+ kobj, err := combinedScheme.New(gvk)
+ if err != nil {
+ return err
+ }
+ err = combinedScheme.Convert(&un, kobj, nil)
+ if err != nil {
+ return err
+ }
+
+ objType := reflect.TypeOf(kobj)
+ if objType.Kind() != reflect.Ptr {
+ return fmt.Errorf("expected pointer type, but got %s", objType.Kind().String())
+ }
+ kobjVal := reflect.ValueOf(kobj).Elem()
+ spec := kobjVal.FieldByName("Spec")
+
+ switch gvk.Kind {
+ case KindEnvoyProxy:
+ typedSpec := spec.Interface()
+ envoyProxy := &egv1a1.EnvoyProxy{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindEnvoyProxy,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(egv1a1.EnvoyProxySpec),
+ }
+ // TODO: only support loading one envoyproxy for now.
+ resources.EnvoyProxyForGatewayClass = envoyProxy
+ case KindGatewayClass:
+ typedSpec := spec.Interface()
+ gatewayClass := &gwapiv1.GatewayClass{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindGatewayClass,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(gwapiv1.GatewayClassSpec),
+ }
+ // fill controller name by default controller name when gatewayclass controller name empty.
+ if addMissingResources && len(gatewayClass.Spec.ControllerName) == 0 {
+ gatewayClass.Spec.ControllerName = egv1a1.GatewayControllerName
+ }
+ resources.GatewayClass = gatewayClass
+ case KindGateway:
+ typedSpec := spec.Interface()
+ gateway := &gwapiv1.Gateway{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindGateway,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(gwapiv1.GatewaySpec),
+ }
+ resources.Gateways = append(resources.Gateways, gateway)
+ case KindTCPRoute:
+ typedSpec := spec.Interface()
+ tcpRoute := &gwapiv1a2.TCPRoute{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindTCPRoute,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(gwapiv1a2.TCPRouteSpec),
+ }
+ resources.TCPRoutes = append(resources.TCPRoutes, tcpRoute)
+ case KindUDPRoute:
+ typedSpec := spec.Interface()
+ udpRoute := &gwapiv1a2.UDPRoute{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindUDPRoute,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(gwapiv1a2.UDPRouteSpec),
+ }
+ resources.UDPRoutes = append(resources.UDPRoutes, udpRoute)
+ case KindTLSRoute:
+ typedSpec := spec.Interface()
+ tlsRoute := &gwapiv1a2.TLSRoute{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindTLSRoute,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(gwapiv1a2.TLSRouteSpec),
+ }
+ resources.TLSRoutes = append(resources.TLSRoutes, tlsRoute)
+ case KindHTTPRoute:
+ typedSpec := spec.Interface()
+ httpRoute := &gwapiv1.HTTPRoute{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindHTTPRoute,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(gwapiv1.HTTPRouteSpec),
+ }
+ resources.HTTPRoutes = append(resources.HTTPRoutes, httpRoute)
+ case KindGRPCRoute:
+ typedSpec := spec.Interface()
+ grpcRoute := &gwapiv1.GRPCRoute{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindGRPCRoute,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(gwapiv1.GRPCRouteSpec),
+ }
+ resources.GRPCRoutes = append(resources.GRPCRoutes, grpcRoute)
+ case KindNamespace:
+ namespace := &corev1.Namespace{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ },
+ }
+ resources.Namespaces = append(resources.Namespaces, namespace)
+ providedNamespaceMap.Insert(name)
+ case KindService:
+ typedSpec := spec.Interface()
+ service := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(corev1.ServiceSpec),
+ }
+ if addMissingResources && len(service.Spec.ClusterIP) == 0 {
+ // fill with dummy IP when service clusterIP is empty
+ service.Spec.ClusterIP = dummyClusterIP
+ }
+ resources.Services = append(resources.Services, service)
+ case KindEnvoyPatchPolicy:
+ typedSpec := spec.Interface()
+ envoyPatchPolicy := &egv1a1.EnvoyPatchPolicy{
+ TypeMeta: metav1.TypeMeta{
+ Kind: egv1a1.KindEnvoyPatchPolicy,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(egv1a1.EnvoyPatchPolicySpec),
+ }
+ resources.EnvoyPatchPolicies = append(resources.EnvoyPatchPolicies, envoyPatchPolicy)
+ case KindClientTrafficPolicy:
+ typedSpec := spec.Interface()
+ clientTrafficPolicy := &egv1a1.ClientTrafficPolicy{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindClientTrafficPolicy,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(egv1a1.ClientTrafficPolicySpec),
+ }
+ resources.ClientTrafficPolicies = append(resources.ClientTrafficPolicies, clientTrafficPolicy)
+ case KindBackendTrafficPolicy:
+ typedSpec := spec.Interface()
+ backendTrafficPolicy := &egv1a1.BackendTrafficPolicy{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindBackendTrafficPolicy,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(egv1a1.BackendTrafficPolicySpec),
+ }
+ resources.BackendTrafficPolicies = append(resources.BackendTrafficPolicies, backendTrafficPolicy)
+ case KindSecurityPolicy:
+ typedSpec := spec.Interface()
+ securityPolicy := &egv1a1.SecurityPolicy{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindSecurityPolicy,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(egv1a1.SecurityPolicySpec),
+ }
+ resources.SecurityPolicies = append(resources.SecurityPolicies, securityPolicy)
+ case KindHTTPRouteFilter:
+ typedSpec := spec.Interface()
+ httpRouteFilter := &egv1a1.HTTPRouteFilter{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindHTTPRouteFilter,
+ APIVersion: egv1a1.GroupVersion.String(),
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: namespace,
+ Name: name,
+ },
+ Spec: typedSpec.(egv1a1.HTTPRouteFilterSpec),
+ }
+ resources.HTTPRouteFilters = append(resources.HTTPRouteFilters, httpRouteFilter)
+ case KindBackend:
+ typedSpec := spec.Interface()
+ backend := &egv1a1.Backend{
+ TypeMeta: metav1.TypeMeta{
+ Kind: KindBackend,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: typedSpec.(egv1a1.BackendSpec),
+ }
+ resources.Backends = append(resources.Backends, backend)
+ }
+
+ return nil
+ }); err != nil {
+ return nil, err
+ }
+
+ if useDefaultNamespace {
+ if !providedNamespaceMap.Has(config.DefaultNamespace) {
+ namespace := &corev1.Namespace{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: config.DefaultNamespace,
+ },
+ }
+ resources.Namespaces = append(resources.Namespaces, namespace)
+ providedNamespaceMap.Insert(config.DefaultNamespace)
+ }
+ }
+
+ if addMissingResources {
+ for ns := range requiredNamespaceMap {
+ if !providedNamespaceMap.Has(ns) {
+ namespace := &corev1.Namespace{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: ns,
+ },
+ }
+ resources.Namespaces = append(resources.Namespaces, namespace)
+ }
+ }
+
+ requiredServiceMap := map[string]*corev1.Service{}
+ for _, route := range resources.TCPRoutes {
+ addMissingServices(requiredServiceMap, route)
+ }
+ for _, route := range resources.UDPRoutes {
+ addMissingServices(requiredServiceMap, route)
+ }
+ for _, route := range resources.TLSRoutes {
+ addMissingServices(requiredServiceMap, route)
+ }
+ for _, route := range resources.HTTPRoutes {
+ addMissingServices(requiredServiceMap, route)
+ }
+ for _, route := range resources.GRPCRoutes {
+ addMissingServices(requiredServiceMap, route)
+ }
+
+ providedServiceMap := map[string]*corev1.Service{}
+ for _, service := range resources.Services {
+ providedServiceMap[service.Namespace+"/"+service.Name] = service
+ }
+
+ for key, service := range requiredServiceMap {
+ if provided, found := providedServiceMap[key]; !found {
+ resources.Services = append(resources.Services, service)
+ } else {
+ providedPorts := sets.NewString()
+ for _, port := range provided.Spec.Ports {
+ portKey := fmt.Sprintf("%s-%d", port.Protocol, port.Port)
+ providedPorts.Insert(portKey)
+ }
+
+ for _, port := range service.Spec.Ports {
+ name := fmt.Sprintf("%s-%d", port.Protocol, port.Port)
+ if !providedPorts.Has(name) {
+ servicePort := corev1.ServicePort{
+ Name: name,
+ Protocol: port.Protocol,
+ Port: port.Port,
+ }
+ provided.Spec.Ports = append(provided.Spec.Ports, servicePort)
+ }
+ }
+ }
+ }
+
+ // Add EnvoyProxy if it does not exist.
+ if resources.EnvoyProxyForGatewayClass == nil {
+ if err := addDefaultEnvoyProxy(resources); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ return resources, nil
+}
+
+func addMissingServices(requiredServices map[string]*corev1.Service, obj interface{}) {
+ var objNamespace string
+ protocol := ir.TCPProtocolType
+
+ var refs []gwapiv1.BackendRef
+ switch route := obj.(type) {
+ case *gwapiv1.HTTPRoute:
+ objNamespace = route.Namespace
+ for _, rule := range route.Spec.Rules {
+ for _, httpBakcendRef := range rule.BackendRefs {
+ refs = append(refs, httpBakcendRef.BackendRef)
+ }
+ }
+ case *gwapiv1.GRPCRoute:
+ objNamespace = route.Namespace
+ for _, rule := range route.Spec.Rules {
+ for _, gRPCBakcendRef := range rule.BackendRefs {
+ refs = append(refs, gRPCBakcendRef.BackendRef)
+ }
+ }
+ case *gwapiv1a2.TLSRoute:
+ objNamespace = route.Namespace
+ for _, rule := range route.Spec.Rules {
+ refs = append(refs, rule.BackendRefs...)
+ }
+ case *gwapiv1a2.TCPRoute:
+ objNamespace = route.Namespace
+ for _, rule := range route.Spec.Rules {
+ refs = append(refs, rule.BackendRefs...)
+ }
+ case *gwapiv1a2.UDPRoute:
+ protocol = ir.UDPProtocolType
+ objNamespace = route.Namespace
+ for _, rule := range route.Spec.Rules {
+ refs = append(refs, rule.BackendRefs...)
+ }
+ }
+
+ for _, ref := range refs {
+ if ref.Kind == nil || *ref.Kind != KindService {
+ continue
+ }
+
+ ns := objNamespace
+ if ref.Namespace != nil {
+ ns = string(*ref.Namespace)
+ }
+ name := string(ref.Name)
+ key := ns + "/" + name
+
+ port := int32(*ref.Port)
+ servicePort := corev1.ServicePort{
+ Name: fmt.Sprintf("%s-%d", protocol, port),
+ Protocol: corev1.Protocol(protocol),
+ Port: port,
+ }
+ if service, found := requiredServices[key]; !found {
+ service := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: ns,
+ },
+ Spec: corev1.ServiceSpec{
+ // Just a dummy IP
+ ClusterIP: dummyClusterIP,
+ Ports: []corev1.ServicePort{servicePort},
+ },
+ }
+ requiredServices[key] = service
+ } else {
+ inserted := false
+ for _, port := range service.Spec.Ports {
+ if port.Protocol == servicePort.Protocol && port.Port == servicePort.Port {
+ inserted = true
+ break
+ }
+ }
+
+ if !inserted {
+ service.Spec.Ports = append(service.Spec.Ports, servicePort)
+ }
+ }
+ }
+}
+
+func addDefaultEnvoyProxy(resources *Resources) error {
+ if resources.GatewayClass == nil {
+ return fmt.Errorf("the GatewayClass resource is required")
+ }
+
+ defaultEnvoyProxyName := "default-envoy-proxy"
+ namespace := resources.GatewayClass.Namespace
+ defaultBootstrapStr, err := bootstrap.GetRenderedBootstrapConfig(nil)
+ if err != nil {
+ return err
+ }
+ ep := &egv1a1.EnvoyProxy{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: namespace,
+ Name: defaultEnvoyProxyName,
+ },
+ Spec: egv1a1.EnvoyProxySpec{
+ Bootstrap: &egv1a1.ProxyBootstrap{
+ Value: &defaultBootstrapStr,
+ },
+ },
+ }
+ resources.EnvoyProxyForGatewayClass = ep
+ ns := gwapiv1.Namespace(namespace)
+ resources.GatewayClass.Spec.ParametersRef = &gwapiv1.ParametersReference{
+ Group: gwapiv1.Group(egv1a1.GroupVersion.Group),
+ Kind: KindEnvoyProxy,
+ Name: defaultEnvoyProxyName,
+ Namespace: &ns,
+ }
+ return nil
+}
+
+// IterYAMLBytes iters every valid YAML resource from YAML bytes
+// and process each of them by calling `handle` callback.
+func IterYAMLBytes(input []byte, handle func([]byte) error) error {
+ reader := utilyaml.NewYAMLReader(bufio.NewReader(bytes.NewBuffer(input)))
+ for {
+ yamlBytes, err := reader.Read()
+ if errors.Is(err, io.EOF) || len(yamlBytes) == 0 {
+ break
+ } else if err != nil {
+ return err
+ }
+ if err = handle(yamlBytes); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/internal/gatewayapi/resource/load_test.go b/internal/gatewayapi/resource/load_test.go
new file mode 100644
index 00000000000..df3629251e9
--- /dev/null
+++ b/internal/gatewayapi/resource/load_test.go
@@ -0,0 +1,39 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package resource
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ "sigs.k8s.io/yaml"
+)
+
+func TestIterYAMLBytes(t *testing.T) {
+ inputs := `test: foo1
+---
+test: foo2
+---
+# This is comment.
+test: foo3
+---
+---
+`
+
+ names := make([]string, 0)
+ err := IterYAMLBytes([]byte(inputs), func(bytes []byte) error {
+ var obj map[string]string
+ err := yaml.Unmarshal(bytes, &obj)
+ require.NoError(t, err)
+
+ if name, ok := obj["test"]; ok {
+ names = append(names, name)
+ }
+ return nil
+ })
+ require.NoError(t, err)
+ require.ElementsMatch(t, names, []string{"foo1", "foo2", "foo3"})
+}
diff --git a/internal/gatewayapi/resource.go b/internal/gatewayapi/resource/resource.go
similarity index 89%
rename from internal/gatewayapi/resource.go
rename to internal/gatewayapi/resource/resource.go
index 3595e9c1c60..749e2efeef6 100644
--- a/internal/gatewayapi/resource.go
+++ b/internal/gatewayapi/resource/resource.go
@@ -3,7 +3,7 @@
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.
-package gatewayapi
+package resource
import (
"cmp"
@@ -13,6 +13,7 @@ import (
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/types"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
@@ -63,6 +64,9 @@ type Resources struct {
EnvoyExtensionPolicies []*egv1a1.EnvoyExtensionPolicy `json:"envoyExtensionPolicies,omitempty" yaml:"envoyExtensionPolicies,omitempty"`
ExtensionServerPolicies []unstructured.Unstructured `json:"extensionServerPolicies,omitempty" yaml:"extensionServerPolicies,omitempty"`
Backends []*egv1a1.Backend `json:"backends,omitempty" yaml:"backends,omitempty"`
+ HTTPRouteFilters []*egv1a1.HTTPRouteFilter `json:"httpFilters,omitempty" yaml:"httpFilters,omitempty"`
+
+ serviceMap map[types.NamespacedName]*corev1.Service
}
func NewResources() *Resources {
@@ -86,6 +90,7 @@ func NewResources() *Resources {
EnvoyExtensionPolicies: []*egv1a1.EnvoyExtensionPolicy{},
ExtensionServerPolicies: []unstructured.Unstructured{},
Backends: []*egv1a1.Backend{},
+ HTTPRouteFilters: []*egv1a1.HTTPRouteFilter{},
}
}
@@ -109,14 +114,20 @@ func (r *Resources) GetEnvoyProxy(namespace, name string) *egv1a1.EnvoyProxy {
return nil
}
+// GetService returns the Service with the given namespace and name.
+// This function creates a HashMap of Services for faster lookup when it's called for the first time.
+// Subsequent calls will use the HashMap for lookup.
+// Note:
+// - This function is not thread-safe.
+// - This function should be called after all the Services are added to the Resources.
func (r *Resources) GetService(namespace, name string) *corev1.Service {
- for _, svc := range r.Services {
- if svc.Namespace == namespace && svc.Name == name {
- return svc
+ if r.serviceMap == nil {
+ r.serviceMap = make(map[types.NamespacedName]*corev1.Service)
+ for _, svc := range r.Services {
+ r.serviceMap[types.NamespacedName{Namespace: svc.Namespace, Name: svc.Name}] = svc
}
}
-
- return nil
+ return r.serviceMap[types.NamespacedName{Namespace: namespace, Name: name}]
}
func (r *Resources) GetServiceImport(namespace, name string) *mcsapiv1a1.ServiceImport {
diff --git a/internal/gatewayapi/resource/resource_test.go b/internal/gatewayapi/resource/resource_test.go
new file mode 100644
index 00000000000..00e39d5db45
--- /dev/null
+++ b/internal/gatewayapi/resource/resource_test.go
@@ -0,0 +1,202 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package resource
+
+import (
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ discoveryv1 "k8s.io/api/discovery/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+)
+
+func TestEqualXds(t *testing.T) {
+ tests := []struct {
+ desc string
+ a *ControllerResources
+ b *ControllerResources
+ equal bool
+ }{
+ {
+ desc: "different resources",
+ a: &ControllerResources{
+ {
+ GatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "foo",
+ },
+ },
+ },
+ },
+ b: &ControllerResources{
+ {
+ GatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "bar",
+ },
+ },
+ },
+ },
+ equal: false,
+ },
+ {
+ desc: "same order resources are equal",
+ a: &ControllerResources{
+ {
+ GatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "foo",
+ },
+ },
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "bar",
+ },
+ },
+ },
+ },
+ b: &ControllerResources{
+ {
+ GatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "foo",
+ },
+ },
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "bar",
+ },
+ },
+ },
+ },
+ equal: true,
+ },
+ {
+ desc: "out of order resources are equal",
+ a: &ControllerResources{
+ {
+ GatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "foo",
+ },
+ },
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "bar",
+ },
+ },
+ },
+ },
+ b: &ControllerResources{
+ {
+ GatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "bar",
+ },
+ },
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "foo",
+ },
+ },
+ },
+ },
+ equal: true,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.desc, func(t *testing.T) {
+ require.Equal(t, tc.equal, cmp.Equal(tc.a, tc.b))
+ })
+ }
+}
+
+func TestGetEndpointSlicesForBackendDualStack(t *testing.T) {
+ // Test data setup
+ dualStackService := &discoveryv1.EndpointSlice{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "dual-stack-service",
+ Namespace: "default",
+ Labels: map[string]string{
+ discoveryv1.LabelServiceName: "my-dual-stack-service",
+ },
+ },
+ AddressType: discoveryv1.AddressTypeIPv4,
+ Endpoints: []discoveryv1.Endpoint{
+ {
+ Addresses: []string{"192.0.2.1"},
+ },
+ {
+ Addresses: []string{"192.0.2.2"},
+ },
+ },
+ }
+
+ dualStackServiceIPv6 := &discoveryv1.EndpointSlice{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "dual-stack-service-ipv6",
+ Namespace: "default",
+ Labels: map[string]string{
+ discoveryv1.LabelServiceName: "my-dual-stack-service",
+ },
+ },
+ AddressType: discoveryv1.AddressTypeIPv6,
+ Endpoints: []discoveryv1.Endpoint{
+ {
+ Addresses: []string{"2001:db8::1"},
+ },
+ {
+ Addresses: []string{"2001:db8::2"},
+ },
+ },
+ }
+
+ resources := &Resources{
+ EndpointSlices: []*discoveryv1.EndpointSlice{dualStackService, dualStackServiceIPv6},
+ }
+
+ t.Run("Dual Stack Service", func(t *testing.T) {
+ result := resources.GetEndpointSlicesForBackend("default", "my-dual-stack-service", KindService)
+
+ assert.Len(t, result, 2, "Expected 2 EndpointSlices for dual-stack service")
+
+ var ipv4Slice, ipv6Slice *discoveryv1.EndpointSlice
+ for _, slice := range result {
+ if slice.AddressType == discoveryv1.AddressTypeIPv4 {
+ ipv4Slice = slice
+ } else if slice.AddressType == discoveryv1.AddressTypeIPv6 {
+ ipv6Slice = slice
+ }
+ }
+
+ assert.NotNil(t, ipv4Slice, "Expected to find an IPv4 EndpointSlice")
+ assert.NotNil(t, ipv6Slice, "Expected to find an IPv6 EndpointSlice")
+
+ if ipv4Slice != nil {
+ assert.Len(t, ipv4Slice.Endpoints, 2, "Expected 2 IPv4 endpoints")
+ assert.Equal(t, "192.0.2.1", ipv4Slice.Endpoints[0].Addresses[0], "Unexpected IPv4 address")
+ assert.Equal(t, "192.0.2.2", ipv4Slice.Endpoints[1].Addresses[0], "Unexpected IPv4 address")
+ }
+
+ if ipv6Slice != nil {
+ assert.Len(t, ipv6Slice.Endpoints, 2, "Expected 2 IPv6 endpoints")
+ assert.Equal(t, "2001:db8::1", ipv6Slice.Endpoints[0].Addresses[0], "Unexpected IPv6 address")
+ assert.Equal(t, "2001:db8::2", ipv6Slice.Endpoints[1].Addresses[0], "Unexpected IPv6 address")
+ }
+ })
+}
diff --git a/internal/gatewayapi/resource/supported_kind.go b/internal/gatewayapi/resource/supported_kind.go
new file mode 100644
index 00000000000..e9d76e66c3d
--- /dev/null
+++ b/internal/gatewayapi/resource/supported_kind.go
@@ -0,0 +1,30 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package resource
+
+const (
+ KindConfigMap = "ConfigMap"
+ KindClientTrafficPolicy = "ClientTrafficPolicy"
+ KindBackendTrafficPolicy = "BackendTrafficPolicy"
+ KindBackendTLSPolicy = "BackendTLSPolicy"
+ KindBackend = "Backend"
+ KindEnvoyPatchPolicy = "EnvoyPatchPolicy"
+ KindEnvoyExtensionPolicy = "EnvoyExtensionPolicy"
+ KindSecurityPolicy = "SecurityPolicy"
+ KindEnvoyProxy = "EnvoyProxy"
+ KindGateway = "Gateway"
+ KindGatewayClass = "GatewayClass"
+ KindGRPCRoute = "GRPCRoute"
+ KindHTTPRoute = "HTTPRoute"
+ KindNamespace = "Namespace"
+ KindTLSRoute = "TLSRoute"
+ KindTCPRoute = "TCPRoute"
+ KindUDPRoute = "UDPRoute"
+ KindService = "Service"
+ KindServiceImport = "ServiceImport"
+ KindSecret = "Secret"
+ KindHTTPRouteFilter = "HTTPRouteFilter"
+)
diff --git a/internal/gatewayapi/resource/validator.go b/internal/gatewayapi/resource/validator.go
new file mode 100644
index 00000000000..beac7564e2a
--- /dev/null
+++ b/internal/gatewayapi/resource/validator.go
@@ -0,0 +1,30 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package resource
+
+import (
+ kvalidate "sigs.k8s.io/kubectl-validate/pkg/cmd"
+ "sigs.k8s.io/kubectl-validate/pkg/openapiclient"
+ "sigs.k8s.io/kubectl-validate/pkg/validator"
+)
+
+var defaultValidator = newDefaultValidator()
+
+// Validator is a local/offline Kubernetes resources validator.
+type Validator struct {
+ resolver *validator.Validator
+}
+
+// newDefaultValidator init a default validator for internal usage.
+func newDefaultValidator() *Validator {
+ factory, _ := validator.New(openapiclient.NewLocalCRDFiles(gatewayCRDsFS))
+ return &Validator{resolver: factory}
+}
+
+// Validate validates one Kubernetes resource.
+func (v Validator) Validate(content []byte) error {
+ return kvalidate.ValidateDocument(content, v.resolver)
+}
diff --git a/internal/gatewayapi/resource/validator_test.go b/internal/gatewayapi/resource/validator_test.go
new file mode 100644
index 00000000000..bbcd267dce3
--- /dev/null
+++ b/internal/gatewayapi/resource/validator_test.go
@@ -0,0 +1,31 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package resource
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ "sigs.k8s.io/kubectl-validate/pkg/openapiclient"
+)
+
+func TestNewOpenAPIClient(t *testing.T) {
+ apiClient := openapiclient.NewLocalCRDFiles(gatewayCRDsFS)
+ gvs, err := apiClient.Paths()
+ require.NoError(t, err)
+
+ groups := make([]string, 0, len(gvs))
+ for g := range gvs {
+ groups = append(groups, g)
+ }
+ require.ElementsMatch(t, groups, []string{
+ "apis/gateway.envoyproxy.io/v1alpha1",
+ "apis/gateway.networking.k8s.io/v1",
+ "apis/gateway.networking.k8s.io/v1alpha2",
+ "apis/gateway.networking.k8s.io/v1alpha3",
+ "apis/gateway.networking.k8s.io/v1beta1",
+ })
+}
diff --git a/internal/gatewayapi/zz_generated.deepcopy.go b/internal/gatewayapi/resource/zz_generated.deepcopy.go
similarity index 91%
rename from internal/gatewayapi/zz_generated.deepcopy.go
rename to internal/gatewayapi/resource/zz_generated.deepcopy.go
index 0ed43eea39d..3caecc292c8 100644
--- a/internal/gatewayapi/zz_generated.deepcopy.go
+++ b/internal/gatewayapi/resource/zz_generated.deepcopy.go
@@ -7,13 +7,14 @@
// Code generated by controller-gen. DO NOT EDIT.
-package gatewayapi
+package resource
import (
"github.com/envoyproxy/gateway/api/v1alpha1"
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/gateway-api/apis/v1"
"sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/gateway-api/apis/v1alpha3"
@@ -279,6 +280,33 @@ func (in *Resources) DeepCopyInto(out *Resources) {
}
}
}
+ if in.HTTPRouteFilters != nil {
+ in, out := &in.HTTPRouteFilters, &out.HTTPRouteFilters
+ *out = make([]*v1alpha1.HTTPRouteFilter, len(*in))
+ for i := range *in {
+ if (*in)[i] != nil {
+ in, out := &(*in)[i], &(*out)[i]
+ *out = new(v1alpha1.HTTPRouteFilter)
+ (*in).DeepCopyInto(*out)
+ }
+ }
+ }
+ if in.serviceMap != nil {
+ in, out := &in.serviceMap, &out.serviceMap
+ *out = make(map[types.NamespacedName]*corev1.Service, len(*in))
+ for key, val := range *in {
+ var outVal *corev1.Service
+ if val == nil {
+ (*out)[key] = nil
+ } else {
+ inVal := (*in)[key]
+ in, out := &inVal, &outVal
+ *out = new(corev1.Service)
+ (*in).DeepCopyInto(*out)
+ }
+ (*out)[key] = outVal
+ }
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resources.
diff --git a/internal/gatewayapi/resource_test.go b/internal/gatewayapi/resource_test.go
deleted file mode 100644
index 8b9fddc0fcd..00000000000
--- a/internal/gatewayapi/resource_test.go
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright Envoy Gateway Authors
-// SPDX-License-Identifier: Apache-2.0
-// The full text of the Apache license is available in the LICENSE file at
-// the root of the repo.
-
-package gatewayapi
-
-import (
- "testing"
-
- "github.com/google/go-cmp/cmp"
- "github.com/stretchr/testify/require"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
-)
-
-func TestEqualXds(t *testing.T) {
- tests := []struct {
- desc string
- a *ControllerResources
- b *ControllerResources
- equal bool
- }{
- {
- desc: "different resources",
- a: &ControllerResources{
- {
- GatewayClass: &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: "foo",
- },
- },
- },
- },
- b: &ControllerResources{
- {
- GatewayClass: &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: "bar",
- },
- },
- },
- },
- equal: false,
- },
- {
- desc: "same order resources are equal",
- a: &ControllerResources{
- {
- GatewayClass: &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: "foo",
- },
- },
- },
- {
- GatewayClass: &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: "bar",
- },
- },
- },
- },
- b: &ControllerResources{
- {
- GatewayClass: &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: "foo",
- },
- },
- },
- {
- GatewayClass: &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: "bar",
- },
- },
- },
- },
- equal: true,
- },
- {
- desc: "out of order resources are equal",
- a: &ControllerResources{
- {
- GatewayClass: &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: "foo",
- },
- },
- },
- {
- GatewayClass: &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: "bar",
- },
- },
- },
- },
- b: &ControllerResources{
- {
- GatewayClass: &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: "bar",
- },
- },
- },
- {
- GatewayClass: &gwapiv1.GatewayClass{
- ObjectMeta: metav1.ObjectMeta{
- Name: "foo",
- },
- },
- },
- },
- equal: true,
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.desc, func(t *testing.T) {
- require.Equal(t, tc.equal, cmp.Equal(tc.a, tc.b))
- })
- }
-}
diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go
index 336e931cfce..ba51d964e6e 100644
--- a/internal/gatewayapi/route.go
+++ b/internal/gatewayapi/route.go
@@ -21,6 +21,7 @@ import (
mcsapiv1a1 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils/regex"
@@ -42,14 +43,14 @@ var (
)
type RoutesTranslator interface {
- ProcessHTTPRoutes(httpRoutes []*gwapiv1.HTTPRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*HTTPRouteContext
- ProcessGRPCRoutes(grpcRoutes []*gwapiv1.GRPCRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*GRPCRouteContext
- ProcessTLSRoutes(tlsRoutes []*gwapiv1a2.TLSRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*TLSRouteContext
- ProcessTCPRoutes(tcpRoutes []*gwapiv1a2.TCPRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*TCPRouteContext
- ProcessUDPRoutes(udpRoutes []*gwapiv1a2.UDPRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*UDPRouteContext
+ ProcessHTTPRoutes(httpRoutes []*gwapiv1.HTTPRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*HTTPRouteContext
+ ProcessGRPCRoutes(grpcRoutes []*gwapiv1.GRPCRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*GRPCRouteContext
+ ProcessTLSRoutes(tlsRoutes []*gwapiv1a2.TLSRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*TLSRouteContext
+ ProcessTCPRoutes(tcpRoutes []*gwapiv1a2.TCPRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*TCPRouteContext
+ ProcessUDPRoutes(udpRoutes []*gwapiv1a2.UDPRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*UDPRouteContext
}
-func (t *Translator) ProcessHTTPRoutes(httpRoutes []*gwapiv1.HTTPRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*HTTPRouteContext {
+func (t *Translator) ProcessHTTPRoutes(httpRoutes []*gwapiv1.HTTPRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*HTTPRouteContext {
var relevantHTTPRoutes []*HTTPRouteContext
for _, h := range httpRoutes {
@@ -77,7 +78,7 @@ func (t *Translator) ProcessHTTPRoutes(httpRoutes []*gwapiv1.HTTPRoute, gateways
return relevantHTTPRoutes
}
-func (t *Translator) ProcessGRPCRoutes(grpcRoutes []*gwapiv1.GRPCRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*GRPCRouteContext {
+func (t *Translator) ProcessGRPCRoutes(grpcRoutes []*gwapiv1.GRPCRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*GRPCRouteContext {
var relevantGRPCRoutes []*GRPCRouteContext
for _, g := range grpcRoutes {
@@ -105,7 +106,7 @@ func (t *Translator) ProcessGRPCRoutes(grpcRoutes []*gwapiv1.GRPCRoute, gateways
return relevantGRPCRoutes
}
-func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, resources *Resources, xdsIR XdsIRMap) {
+func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, resources *resource.Resources, xdsIR resource.XdsIRMap) {
for _, parentRef := range httpRoute.ParentRefs {
// Need to compute Route rules within the parentRef loop because
// any conditions that come out of it have to go on each RouteParentStatus,
@@ -172,7 +173,7 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res
}
}
-func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRef *RouteParentContext, resources *Resources) ([]*ir.HTTPRoute, error) {
+func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRef *RouteParentContext, resources *resource.Resources) ([]*ir.HTTPRoute, error) {
var routeRoutes []*ir.HTTPRoute
var envoyProxy *egv1a1.EnvoyProxy
@@ -183,8 +184,10 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe
// compute matches, filters, backends
for ruleIdx, rule := range httpRoute.Spec.Rules {
- httpFiltersContext := t.ProcessHTTPFilters(parentRef, httpRoute, rule.Filters, ruleIdx, resources)
-
+ httpFiltersContext, err := t.ProcessHTTPFilters(parentRef, httpRoute, rule.Filters, ruleIdx, resources)
+ if err != nil {
+ return nil, err
+ }
// A rule is matched if any one of its matches
// is satisfied (i.e. a logical "OR"), so generate
// a unique Xds IR HTTPRoute per match.
@@ -196,17 +199,23 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe
dstAddrTypeMap := make(map[ir.DestinationAddressType]int)
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
- ds := t.processDestination(backendRef, parentRef, httpRoute, resources)
-
+ ds, err := t.processDestination(backendRef, parentRef, httpRoute, resources)
if !t.IsEnvoyServiceRouting(envoyProxy) && ds != nil && len(ds.Endpoints) > 0 && ds.AddressType != nil {
dstAddrTypeMap[*ds.AddressType]++
}
- if ds == nil {
- continue
- }
for _, route := range ruleRoutes {
+ // disable associated routes to a backend ref in case some of its config was invalid
+ if err != nil {
+ route.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
+ }
+ continue
+ }
+
+ if ds == nil {
+ continue
+ }
// If the route already has a direct response or redirect configured, then it was from a filter so skip
// processing any destinations for this route.
if route.DirectResponse != nil || route.Redirect != nil {
@@ -237,9 +246,9 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe
// If the route has no valid backends then just use a direct response and don't fuss with weighted responses
for _, ruleRoute := range ruleRoutes {
noValidBackends := ruleRoute.Destination == nil || ruleRoute.Destination.ToBackendWeights().Valid == 0
- if noValidBackends && ruleRoute.Redirect == nil {
- ruleRoute.DirectResponse = &ir.DirectResponse{
- StatusCode: 500,
+ if ruleRoute.DirectResponse == nil && noValidBackends && ruleRoute.Redirect == nil {
+ ruleRoute.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
}
}
ruleRoute.IsHTTP2 = false
@@ -255,23 +264,14 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe
return routeRoutes, nil
}
-func processTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) {
+func processRouteTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) {
if rule.Timeouts != nil {
- var rto *ir.Timeout
-
- // Timeout is translated from multiple resources and may already be partially set
- if irRoute.Traffic != nil && irRoute.Traffic.Timeout != nil {
- rto = irRoute.Traffic.Timeout.DeepCopy()
- } else {
- rto = &ir.Timeout{}
- }
-
if rule.Timeouts.Request != nil {
d, err := time.ParseDuration(string(*rule.Timeouts.Request))
if err != nil {
d, _ = time.ParseDuration(HTTPRequestTimeout)
}
- setRequestTimeout(rto, metav1.Duration{Duration: d})
+ irRoute.Timeout = ptr.To(metav1.Duration{Duration: d})
}
// Also set the IR Route Timeout to the backend request timeout
@@ -281,26 +281,11 @@ func processTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) {
if err != nil {
d, _ = time.ParseDuration(HTTPRequestTimeout)
}
- setRequestTimeout(rto, metav1.Duration{Duration: d})
- }
-
- irRoute.Traffic = &ir.TrafficFeatures{
- Timeout: rto,
+ irRoute.Timeout = ptr.To(metav1.Duration{Duration: d})
}
}
}
-func setRequestTimeout(irTimeout *ir.Timeout, d metav1.Duration) {
- switch {
- case irTimeout.HTTP == nil:
- irTimeout.HTTP = &ir.HTTPTimeout{
- RequestTimeout: ptr.To(d),
- }
- default:
- irTimeout.HTTP.RequestTimeout = ptr.To(d)
- }
-}
-
func (t *Translator) processHTTPRouteRule(httpRoute *HTTPRouteContext, ruleIdx int, httpFiltersContext *HTTPFiltersContext, rule gwapiv1.HTTPRouteRule) ([]*ir.HTTPRoute, error) {
var ruleRoutes []*ir.HTTPRoute
@@ -309,19 +294,69 @@ func (t *Translator) processHTTPRouteRule(httpRoute *HTTPRouteContext, ruleIdx i
irRoute := &ir.HTTPRoute{
Name: irRouteName(httpRoute, ruleIdx, -1),
}
- processTimeout(irRoute, rule)
+ irRoute.Metadata = buildRouteMetadata(httpRoute, rule.Name)
+ processRouteTimeout(irRoute, rule)
applyHTTPFiltersContextToIRRoute(httpFiltersContext, irRoute)
ruleRoutes = append(ruleRoutes, irRoute)
}
+ var sessionPersistence *ir.SessionPersistence
+ if rule.SessionPersistence != nil {
+ if rule.SessionPersistence.IdleTimeout != nil {
+ return nil, fmt.Errorf("idle timeout is not supported in envoy gateway")
+ }
+
+ var sessionName string
+ if rule.SessionPersistence.SessionName == nil {
+ // SessionName is optional on the gateway-api, but envoy requires it
+ // so we generate the one here.
+
+ // We generate a unique session name per route.
+ // `/` isn't allowed in the header key, so we just replace it with `-`.
+ sessionName = strings.ReplaceAll(irRouteDestinationName(httpRoute, ruleIdx), "/", "-")
+ } else {
+ sessionName = *rule.SessionPersistence.SessionName
+ }
+
+ switch {
+ case rule.SessionPersistence.Type == nil || // Cookie-based session persistence is default.
+ *rule.SessionPersistence.Type == gwapiv1.CookieBasedSessionPersistence:
+ sessionPersistence = &ir.SessionPersistence{
+ Cookie: &ir.CookieBasedSessionPersistence{
+ Name: sessionName,
+ },
+ }
+ if rule.SessionPersistence.AbsoluteTimeout != nil &&
+ rule.SessionPersistence.CookieConfig != nil && rule.SessionPersistence.CookieConfig.LifetimeType != nil &&
+ *rule.SessionPersistence.CookieConfig.LifetimeType == gwapiv1.PermanentCookieLifetimeType {
+ ttl, err := time.ParseDuration(string(*rule.SessionPersistence.AbsoluteTimeout))
+ if err != nil {
+ return nil, err
+ }
+ sessionPersistence.Cookie.TTL = &metav1.Duration{Duration: ttl}
+ }
+ case *rule.SessionPersistence.Type == gwapiv1.HeaderBasedSessionPersistence:
+ sessionPersistence = &ir.SessionPersistence{
+ Header: &ir.HeaderBasedSessionPersistence{
+ Name: sessionName,
+ },
+ }
+ default:
+ // Unknown session persistence type is specified.
+ return nil, fmt.Errorf("unknown session persistence type %s", *rule.SessionPersistence.Type)
+ }
+ }
+
// A rule is matched if any one of its matches
// is satisfied (i.e. a logical "OR"), so generate
// a unique Xds IR HTTPRoute per match.
for matchIdx, match := range rule.Matches {
irRoute := &ir.HTTPRoute{
- Name: irRouteName(httpRoute, ruleIdx, matchIdx),
+ Name: irRouteName(httpRoute, ruleIdx, matchIdx),
+ SessionPersistence: sessionPersistence,
}
- processTimeout(irRoute, rule)
+ irRoute.Metadata = buildRouteMetadata(httpRoute, rule.Name)
+ processRouteTimeout(irRoute, rule)
if match.Path != nil {
switch PathMatchTypeDerefOr(match.Path.Type, gwapiv1.PathMatchPathPrefix) {
@@ -422,7 +457,7 @@ func applyHTTPFiltersContextToIRRoute(httpFiltersContext *HTTPFiltersContext, ir
}
}
-func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, resources *Resources, xdsIR XdsIRMap) {
+func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, resources *resource.Resources, xdsIR resource.XdsIRMap) {
for _, parentRef := range grpcRoute.ParentRefs {
// Need to compute Route rules within the parentRef loop because
@@ -488,13 +523,15 @@ func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, res
}
}
-func (t *Translator) processGRPCRouteRules(grpcRoute *GRPCRouteContext, parentRef *RouteParentContext, resources *Resources) ([]*ir.HTTPRoute, error) {
+func (t *Translator) processGRPCRouteRules(grpcRoute *GRPCRouteContext, parentRef *RouteParentContext, resources *resource.Resources) ([]*ir.HTTPRoute, error) {
var routeRoutes []*ir.HTTPRoute
// compute matches, filters, backends
for ruleIdx, rule := range grpcRoute.Spec.Rules {
- httpFiltersContext := t.ProcessGRPCFilters(parentRef, grpcRoute, rule.Filters, resources)
-
+ httpFiltersContext, err := t.ProcessGRPCFilters(parentRef, grpcRoute, rule.Filters, resources)
+ if err != nil {
+ return nil, err
+ }
// A rule is matched if any one of its matches
// is satisfied (i.e. a logical "OR"), so generate
// a unique Xds IR HTTPRoute per match.
@@ -504,8 +541,7 @@ func (t *Translator) processGRPCRouteRules(grpcRoute *GRPCRouteContext, parentRe
}
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
- ds := t.processDestination(backendRef, parentRef, grpcRoute, resources)
+ ds, err := t.processDestination(backendRef, parentRef, grpcRoute, resources)
if ds == nil {
continue
}
@@ -517,6 +553,13 @@ func (t *Translator) processGRPCRouteRules(grpcRoute *GRPCRouteContext, parentRe
continue
}
+ // disable associated routes to a backend ref in case some of its config was invalid
+ if err != nil {
+ route.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
+ }
+ }
+
if route.Destination == nil {
route.Destination = &ir.RouteDestination{
Name: irRouteDestinationName(grpcRoute, ruleIdx),
@@ -530,8 +573,8 @@ func (t *Translator) processGRPCRouteRules(grpcRoute *GRPCRouteContext, parentRe
for _, ruleRoute := range ruleRoutes {
noValidBackends := ruleRoute.Destination == nil || ruleRoute.Destination.ToBackendWeights().Valid == 0
if noValidBackends && ruleRoute.Redirect == nil {
- ruleRoute.DirectResponse = &ir.DirectResponse{
- StatusCode: 500,
+ ruleRoute.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
}
}
ruleRoute.IsHTTP2 = true
@@ -555,6 +598,7 @@ func (t *Translator) processGRPCRouteRule(grpcRoute *GRPCRouteContext, ruleIdx i
irRoute := &ir.HTTPRoute{
Name: irRouteName(grpcRoute, ruleIdx, -1),
}
+ irRoute.Metadata = buildRouteMetadata(grpcRoute, rule.Name)
applyHTTPFiltersContextToIRRoute(httpFiltersContext, irRoute)
ruleRoutes = append(ruleRoutes, irRoute)
}
@@ -566,15 +610,15 @@ func (t *Translator) processGRPCRouteRule(grpcRoute *GRPCRouteContext, ruleIdx i
irRoute := &ir.HTTPRoute{
Name: irRouteName(grpcRoute, ruleIdx, matchIdx),
}
-
+ irRoute.Metadata = buildRouteMetadata(grpcRoute, rule.Name)
for _, headerMatch := range match.Headers {
- switch HeaderMatchTypeDerefOr(headerMatch.Type, gwapiv1.HeaderMatchExact) {
- case gwapiv1.HeaderMatchExact:
+ switch GRPCHeaderMatchTypeDerefOr(headerMatch.Type, gwapiv1.GRPCHeaderMatchExact) {
+ case gwapiv1.GRPCHeaderMatchExact:
irRoute.HeaderMatches = append(irRoute.HeaderMatches, &ir.StringMatch{
Name: string(headerMatch.Name),
Exact: ptr.To(headerMatch.Value),
})
- case gwapiv1.HeaderMatchRegularExpression:
+ case gwapiv1.GRPCHeaderMatchRegularExpression:
if err := regex.Validate(headerMatch.Value); err != nil {
return nil, err
}
@@ -647,16 +691,15 @@ func (t *Translator) processGRPCRouteMethodRegularExpression(method *gwapiv1.GRP
}
}
-func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, routeRoutes []*ir.HTTPRoute, parentRef *RouteParentContext, xdsIR XdsIRMap) bool {
+func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, routeRoutes []*ir.HTTPRoute, parentRef *RouteParentContext, xdsIR resource.XdsIRMap) bool {
var hasHostnameIntersection bool
for _, listener := range parentRef.listeners {
- hosts := computeHosts(GetHostnames(route), listener.Hostname)
+ hosts := computeHosts(GetHostnames(route), listener)
if len(hosts) == 0 {
continue
}
hasHostnameIntersection = true
- routeMetadata := buildRouteMetadata(route)
var perHostRoutes []*ir.HTTPRoute
for _, host := range hosts {
@@ -683,7 +726,7 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route
underscoredHost := strings.ReplaceAll(host, ".", "_")
hostRoute := &ir.HTTPRoute{
Name: fmt.Sprintf("%s/%s", routeRoute.Name, underscoredHost),
- Metadata: routeMetadata,
+ Metadata: routeRoute.Metadata,
Hostname: host,
PathMatch: routeRoute.PathMatch,
HeaderMatches: routeRoute.HeaderMatches,
@@ -699,11 +742,12 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route
Mirrors: routeRoute.Mirrors,
ExtensionRefs: routeRoute.ExtensionRefs,
IsHTTP2: routeRoute.IsHTTP2,
+ SessionPersistence: routeRoute.SessionPersistence,
+ Timeout: routeRoute.Timeout,
}
if routeRoute.Traffic != nil {
hostRoute.Traffic = &ir.TrafficFeatures{
- Timeout: routeRoute.Traffic.Timeout,
- Retry: routeRoute.Traffic.Retry,
+ Retry: routeRoute.Traffic.Retry,
}
}
perHostRoutes = append(perHostRoutes, hostRoute)
@@ -713,7 +757,7 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route
irListener := xdsIR[irKey].GetHTTPListener(irListenerName(listener))
if irListener != nil {
- if GetRouteType(route) == KindGRPCRoute {
+ if GetRouteType(route) == resource.KindGRPCRoute {
irListener.IsHTTP2 = true
}
irListener.Routes = append(irListener.Routes, perHostRoutes...)
@@ -723,13 +767,17 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route
return hasHostnameIntersection
}
-func buildRouteMetadata(route RouteContext) *ir.ResourceMetadata {
- return &ir.ResourceMetadata{
+func buildRouteMetadata(route RouteContext, sectionName *gwapiv1.SectionName) *ir.ResourceMetadata {
+ metadata := &ir.ResourceMetadata{
Kind: route.GetObjectKind().GroupVersionKind().Kind,
Name: route.GetName(),
Namespace: route.GetNamespace(),
Annotations: filterEGPrefix(route.GetAnnotations()),
}
+ if sectionName != nil {
+ metadata.SectionName = string(*sectionName)
+ }
+ return metadata
}
func filterEGPrefix(in map[string]string) map[string]string {
@@ -745,7 +793,7 @@ func filterEGPrefix(in map[string]string) map[string]string {
return out
}
-func (t *Translator) ProcessTLSRoutes(tlsRoutes []*gwapiv1a2.TLSRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*TLSRouteContext {
+func (t *Translator) ProcessTLSRoutes(tlsRoutes []*gwapiv1a2.TLSRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*TLSRouteContext {
var relevantTLSRoutes []*TLSRouteContext
for _, tls := range tlsRoutes {
@@ -773,7 +821,7 @@ func (t *Translator) ProcessTLSRoutes(tlsRoutes []*gwapiv1a2.TLSRoute, gateways
return relevantTLSRoutes
}
-func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resources *Resources, xdsIR XdsIRMap) {
+func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resources *resource.Resources, xdsIR resource.XdsIRMap) {
for _, parentRef := range tlsRoute.ParentRefs {
// Need to compute Route rules within the parentRef loop because
@@ -784,8 +832,8 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
// compute backends
for _, rule := range tlsRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
- ds := t.processDestination(backendRef, parentRef, tlsRoute, resources)
+ // not yet handled, requires to align with the conformance test - TLSRouteInvalidReferenceGrant.
+ ds, _ := t.processDestination(backendRef, parentRef, tlsRoute, resources)
if ds != nil {
destSettings = append(destSettings, ds)
}
@@ -818,7 +866,7 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
var hasHostnameIntersection bool
for _, listener := range parentRef.listeners {
- hosts := computeHosts(GetHostnames(tlsRoute), listener.Hostname)
+ hosts := computeHosts(GetHostnames(tlsRoute), listener)
if len(hosts) == 0 {
continue
}
@@ -873,8 +921,8 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
}
}
-func (t *Translator) ProcessUDPRoutes(udpRoutes []*gwapiv1a2.UDPRoute, gateways []*GatewayContext, resources *Resources,
- xdsIR XdsIRMap,
+func (t *Translator) ProcessUDPRoutes(udpRoutes []*gwapiv1a2.UDPRoute, gateways []*GatewayContext, resources *resource.Resources,
+ xdsIR resource.XdsIRMap,
) []*UDPRouteContext {
var relevantUDPRoutes []*UDPRouteContext
@@ -903,7 +951,7 @@ func (t *Translator) ProcessUDPRoutes(udpRoutes []*gwapiv1a2.UDPRoute, gateways
return relevantUDPRoutes
}
-func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resources *Resources, xdsIR XdsIRMap) {
+func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resources *resource.Resources, xdsIR resource.XdsIRMap) {
for _, parentRef := range udpRoute.ParentRefs {
// Need to compute Route rules within the parentRef loop because
// any conditions that come out of it have to go on each RouteParentStatus,
@@ -925,11 +973,20 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour
}
for _, backendRef := range udpRoute.Spec.Rules[0].BackendRefs {
- ds := t.processDestination(backendRef, parentRef, udpRoute, resources)
- if ds == nil {
+ ds, err := t.processDestination(backendRef, parentRef, udpRoute, resources)
+ // skip adding the route and provide the reason via route status.
+ if err != nil {
+ routeStatus := GetRouteStatus(udpRoute)
+ status.SetRouteStatusCondition(routeStatus,
+ parentRef.routeParentStatusIdx,
+ udpRoute.GetGeneration(),
+ gwapiv1.RouteConditionAccepted,
+ metav1.ConditionFalse,
+ "Failed to process the settings associated with the UDP route.",
+ err.Error(),
+ )
continue
}
-
destSettings = append(destSettings, ds)
}
@@ -1006,8 +1063,8 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour
}
}
-func (t *Translator) ProcessTCPRoutes(tcpRoutes []*gwapiv1a2.TCPRoute, gateways []*GatewayContext, resources *Resources,
- xdsIR XdsIRMap,
+func (t *Translator) ProcessTCPRoutes(tcpRoutes []*gwapiv1a2.TCPRoute, gateways []*GatewayContext, resources *resource.Resources,
+ xdsIR resource.XdsIRMap,
) []*TCPRouteContext {
var relevantTCPRoutes []*TCPRouteContext
@@ -1036,7 +1093,7 @@ func (t *Translator) ProcessTCPRoutes(tcpRoutes []*gwapiv1a2.TCPRoute, gateways
return relevantTCPRoutes
}
-func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resources *Resources, xdsIR XdsIRMap) {
+func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resources *resource.Resources, xdsIR resource.XdsIRMap) {
for _, parentRef := range tcpRoute.ParentRefs {
// Need to compute Route rules within the parentRef loop because
// any conditions that come out of it have to go on each RouteParentStatus,
@@ -1058,12 +1115,20 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour
}
for _, backendRef := range tcpRoute.Spec.Rules[0].BackendRefs {
- backendRef := backendRef
- ds := t.processDestination(backendRef, parentRef, tcpRoute, resources)
- if ds == nil {
+ ds, err := t.processDestination(backendRef, parentRef, tcpRoute, resources)
+ // skip adding the route and provide the reason via route status.
+ if err != nil {
+ routeStatus := GetRouteStatus(tcpRoute)
+ status.SetRouteStatusCondition(routeStatus,
+ parentRef.routeParentStatusIdx,
+ tcpRoute.GetGeneration(),
+ gwapiv1.RouteConditionAccepted,
+ metav1.ConditionFalse,
+ "Failed to process the settings associated with the TCP route.",
+ err.Error(),
+ )
continue
}
-
destSettings = append(destSettings, ds)
}
@@ -1152,12 +1217,12 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour
}
}
-// processDestination takes a backendRef and translates it into destination setting or sets error statuses and
-// returns the weight for the backend so that 500 error responses can be returned for invalid backends in
-// the same proportion as the backend would have otherwise received
+// processDestination translates a backendRef into a destination settings.
+// If an error occurs during this conversion, an error is returned, and the associated routes are expected to become inactive.
+// This will result in a direct 500 response for HTTP-based requests.
func (t *Translator) processDestination(backendRefContext BackendRefContext,
- parentRef *RouteParentContext, route RouteContext, resources *Resources,
-) (ds *ir.DestinationSetting) {
+ parentRef *RouteParentContext, route RouteContext, resources *resource.Resources,
+) (ds *ir.DestinationSetting, err error) {
routeType := GetRouteType(route)
weight := uint32(1)
backendRef := GetBackendRef(backendRefContext)
@@ -1166,14 +1231,17 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
}
backendNamespace := NamespaceDerefOr(backendRef.Namespace, route.GetNamespace())
- if !t.validateBackendRef(backendRefContext, parentRef, route, resources, backendNamespace, routeType) {
- // return with empty endpoint means the backend is invalid
- return &ir.DestinationSetting{Weight: &weight}
+ err = t.validateBackendRef(backendRefContext, parentRef, route, resources, backendNamespace, routeType)
+ {
+ // return with empty endpoint means the backend is invalid and an error to fail the associated route.
+ if err != nil {
+ return nil, err
+ }
}
// Skip processing backends with 0 weight
if weight == 0 {
- return nil
+ return nil, nil
}
var envoyProxy *egv1a1.EnvoyProxy
@@ -1187,8 +1255,9 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
addrType *ir.DestinationAddressType
)
protocol := inspectAppProtocolByRouteKind(routeType)
- switch KindDerefOr(backendRef.Kind, KindService) {
- case KindServiceImport:
+
+ switch KindDerefOr(backendRef.Kind, resource.KindService) {
+ case resource.KindServiceImport:
serviceImport := resources.GetServiceImport(backendNamespace, string(backendRef.Name))
var servicePort mcsapiv1a1.ServicePort
for _, port := range serviceImport.Spec.Ports {
@@ -1199,7 +1268,7 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
}
if !t.IsEnvoyServiceRouting(envoyProxy) {
- endpointSlices := resources.GetEndpointSlicesForBackend(backendNamespace, string(backendRef.Name), KindDerefOr(backendRef.Kind, KindService))
+ endpointSlices := resources.GetEndpointSlicesForBackend(backendNamespace, string(backendRef.Name), KindDerefOr(backendRef.Kind, resource.KindService))
endpoints, addrType = getIREndpointsFromEndpointSlices(endpointSlices, servicePort.Name, servicePort.Protocol)
} else {
backendIps := resources.GetServiceImport(backendNamespace, string(backendRef.Name)).Spec.IPs
@@ -1217,10 +1286,10 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
Endpoints: endpoints,
AddressType: addrType,
}
- case KindService:
- ds = t.processServiceDestinationSetting(backendRef.BackendObjectReference, backendNamespace, protocol, resources, envoyProxy)
- ds.TLS = t.applyBackendTLSSetting(
+ case resource.KindService:
+ ds = t.processServiceDestinationSetting(backendRef.BackendObjectReference, backendNamespace, protocol, resources, envoyProxy)
+ ds.TLS, err = t.applyBackendTLSSetting(
backendRef.BackendObjectReference,
backendNamespace,
gwapiv1a2.ParentReference{
@@ -1234,11 +1303,17 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
resources,
envoyProxy,
)
- ds.Filters = t.processDestinationFilters(routeType, backendRefContext, parentRef, route, resources)
+ if err != nil {
+ return nil, err
+ }
+ ds.Filters, err = t.processDestinationFilters(routeType, backendRefContext, parentRef, route, resources)
+ if err != nil {
+ return nil, err
+ }
+ ds.IPFamily = getServiceIPFamily(resources.GetService(backendNamespace, string(backendRef.Name)))
case egv1a1.KindBackend:
ds = t.processBackendDestinationSetting(backendRef.BackendObjectReference, backendNamespace, resources)
-
- ds.TLS = t.applyBackendTLSSetting(
+ ds.TLS, err = t.applyBackendTLSSetting(
backendRef.BackendObjectReference,
backendNamespace,
gwapiv1a2.ParentReference{
@@ -1252,7 +1327,13 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
resources,
envoyProxy,
)
- ds.Filters = t.processDestinationFilters(routeType, backendRefContext, parentRef, route, resources)
+ if err != nil {
+ return nil, err
+ }
+ ds.Filters, err = t.processDestinationFilters(routeType, backendRefContext, parentRef, route, resources)
+ if err != nil {
+ return nil, err
+ }
}
if err := validateDestinationSettings(ds, t.IsEnvoyServiceRouting(envoyProxy), backendRef.Kind); err != nil {
@@ -1264,20 +1345,21 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
metav1.ConditionFalse,
gwapiv1.RouteReasonResolvedRefs,
err.Error())
+ return nil, err
}
ds.Weight = &weight
- return ds
+ return ds, nil
}
func validateDestinationSettings(destinationSettings *ir.DestinationSetting, endpointRoutingDisabled bool, kind *gwapiv1.Kind) error {
// TODO: support mixed endpointslice address type for the same backendRef
- switch KindDerefOr(kind, KindService) {
+ switch KindDerefOr(kind, resource.KindService) {
case egv1a1.KindBackend:
if destinationSettings.AddressType != nil && *destinationSettings.AddressType == ir.MIXED {
return fmt.Errorf("mixed FQDN and IP or Unix address type for the same backendRef is not supported")
}
- case KindService, KindServiceImport:
+ case resource.KindService, resource.KindServiceImport:
if !endpointRoutingDisabled && destinationSettings.AddressType != nil && *destinationSettings.AddressType == ir.MIXED {
return fmt.Errorf("mixed endpointslice address type for the same backendRef is not supported")
}
@@ -1290,7 +1372,7 @@ func (t *Translator) processServiceDestinationSetting(
backendRef gwapiv1.BackendObjectReference,
backendNamespace string,
protocol ir.AppProtocol,
- resources *Resources,
+ resources *resource.Resources,
envoyProxy *egv1a1.EnvoyProxy,
) *ir.DestinationSetting {
var (
@@ -1319,7 +1401,7 @@ func (t *Translator) processServiceDestinationSetting(
// Route to endpoints by default
if !t.IsEnvoyServiceRouting(envoyProxy) {
- endpointSlices := resources.GetEndpointSlicesForBackend(backendNamespace, string(backendRef.Name), KindDerefOr(backendRef.Kind, KindService))
+ endpointSlices := resources.GetEndpointSlicesForBackend(backendNamespace, string(backendRef.Name), KindDerefOr(backendRef.Kind, resource.KindService))
endpoints, addrType = getIREndpointsFromEndpointSlices(endpointSlices, servicePort.Name, servicePort.Protocol)
} else {
// Fall back to Service ClusterIP routing
@@ -1339,11 +1421,11 @@ func (t *Translator) processServiceDestinationSetting(
func getBackendFilters(routeType gwapiv1.Kind, backendRefContext BackendRefContext) (backendFilters any) {
filters := GetFilters(backendRefContext)
switch routeType {
- case KindHTTPRoute:
+ case resource.KindHTTPRoute:
if len(filters.([]gwapiv1.HTTPRouteFilter)) > 0 {
return filters.([]gwapiv1.HTTPRouteFilter)
}
- case KindGRPCRoute:
+ case resource.KindGRPCRoute:
if len(filters.([]gwapiv1.GRPCRouteFilter)) > 0 {
return filters.([]gwapiv1.GRPCRouteFilter)
}
@@ -1352,25 +1434,29 @@ func getBackendFilters(routeType gwapiv1.Kind, backendRefContext BackendRefConte
return nil
}
-func (t *Translator) processDestinationFilters(routeType gwapiv1.Kind, backendRefContext BackendRefContext, parentRef *RouteParentContext, route RouteContext, resources *Resources) *ir.DestinationFilters {
+func (t *Translator) processDestinationFilters(routeType gwapiv1.Kind, backendRefContext BackendRefContext, parentRef *RouteParentContext, route RouteContext, resources *resource.Resources) (*ir.DestinationFilters, error) {
backendFilters := getBackendFilters(routeType, backendRefContext)
if backendFilters == nil {
- return nil
+ return nil, nil
}
var httpFiltersContext *HTTPFiltersContext
var destFilters ir.DestinationFilters
+ var err error
switch filters := backendFilters.(type) {
case []gwapiv1.HTTPRouteFilter:
- httpFiltersContext = t.ProcessHTTPFilters(parentRef, route, filters, 0, resources)
+ httpFiltersContext, err = t.ProcessHTTPFilters(parentRef, route, filters, 0, resources)
case []gwapiv1.GRPCRouteFilter:
- httpFiltersContext = t.ProcessGRPCFilters(parentRef, route, filters, resources)
+ httpFiltersContext, err = t.ProcessGRPCFilters(parentRef, route, filters, resources)
+ if err != nil {
+ return &destFilters, err
+ }
}
applyHTTPFiltersContextToDestinationFilters(httpFiltersContext, &destFilters)
- return &destFilters
+ return &destFilters, err
}
func applyHTTPFiltersContextToDestinationFilters(httpFiltersContext *HTTPFiltersContext, destFilters *ir.DestinationFilters) {
@@ -1390,15 +1476,15 @@ func applyHTTPFiltersContextToDestinationFilters(httpFiltersContext *HTTPFilters
func inspectAppProtocolByRouteKind(kind gwapiv1.Kind) ir.AppProtocol {
switch kind {
- case KindUDPRoute:
+ case resource.KindUDPRoute:
return ir.UDP
- case KindHTTPRoute:
+ case resource.KindHTTPRoute:
return ir.HTTP
- case KindTCPRoute:
+ case resource.KindTCPRoute:
return ir.TCP
- case KindGRPCRoute:
+ case resource.KindGRPCRoute:
return ir.GRPC
- case KindTLSRoute:
+ case resource.KindTLSRoute:
return ir.HTTPS
}
return ir.TCP
@@ -1407,7 +1493,7 @@ func inspectAppProtocolByRouteKind(kind gwapiv1.Kind) ir.AppProtocol {
// processAllowedListenersForParentRefs finds out if the route attaches to one of our
// Gateways' listeners, and if so, gets the list of listeners that allow it to
// attach for each parentRef.
-func (t *Translator) processAllowedListenersForParentRefs(routeContext RouteContext, gateways []*GatewayContext, resources *Resources) bool {
+func (t *Translator) processAllowedListenersForParentRefs(routeContext RouteContext, gateways []*GatewayContext, resources *resource.Resources) bool {
var relevantRoute bool
ns := gwapiv1.Namespace(routeContext.GetNamespace())
for _, parentRef := range GetParentReferences(routeContext) {
@@ -1550,34 +1636,49 @@ func getIREndpointsFromEndpointSlice(endpointSlice *discoveryv1.EndpointSlice, p
return endpoints
}
-func getTargetBackendReference(backendRef gwapiv1a2.BackendObjectReference) gwapiv1a2.LocalPolicyTargetReferenceWithSectionName {
+func getTargetBackendReference(backendRef gwapiv1a2.BackendObjectReference, backendNamespace string, resources *resource.Resources) gwapiv1a2.LocalPolicyTargetReferenceWithSectionName {
ref := gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{
LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{
Group: func() gwapiv1a2.Group {
- if backendRef.Group == nil {
+ if backendRef.Group == nil || *backendRef.Group == "" {
return ""
}
return *backendRef.Group
}(),
Kind: func() gwapiv1.Kind {
- if backendRef.Kind == nil {
+ if backendRef.Kind == nil || *backendRef.Kind == resource.KindService {
return "Service"
}
return *backendRef.Kind
}(),
Name: backendRef.Name,
},
- SectionName: func() *gwapiv1.SectionName {
- if backendRef.Port != nil {
- return SectionNamePtr(strconv.Itoa(int(*backendRef.Port)))
+ }
+ if backendRef.Port == nil {
+ return ref
+ }
+
+ // Set the section name to the port name if the backend is a Kubernetes Service
+ if backendRef.Kind == nil || *backendRef.Kind == resource.KindService {
+ if service := resources.GetService(backendNamespace, string(backendRef.Name)); service != nil {
+ for _, port := range service.Spec.Ports {
+ if port.Port == int32(*backendRef.Port) {
+ if port.Name != "" {
+ ref.SectionName = SectionNamePtr(port.Name)
+ break
+ }
+ }
}
- return nil
- }(),
+ }
+ } else {
+ // Set the section name to the port number if the backend is a EG Backend
+ ref.SectionName = SectionNamePtr(strconv.Itoa(int(*backendRef.Port)))
}
+
return ref
}
-func (t *Translator) processBackendDestinationSetting(backendRef gwapiv1.BackendObjectReference, backendNamespace string, resources *Resources) *ir.DestinationSetting {
+func (t *Translator) processBackendDestinationSetting(backendRef gwapiv1.BackendObjectReference, backendNamespace string, resources *resource.Resources) *ir.DestinationSetting {
var (
dstEndpoints []*ir.DestinationEndpoint
dstAddrType *ir.DestinationAddressType
@@ -1633,9 +1734,18 @@ func (t *Translator) processBackendDestinationSetting(backendRef gwapiv1.Backend
}
}
- return &ir.DestinationSetting{
+ ds := &ir.DestinationSetting{
Protocol: dstProtocol,
Endpoints: dstEndpoints,
AddressType: dstAddrType,
}
+
+ if backend.Spec.Fallback != nil {
+ // set only the secondary priority, the backend defaults to a primary priority if unset.
+ if ptr.Deref(backend.Spec.Fallback, false) {
+ ds.Priority = ptr.To(uint32(1))
+ }
+ }
+
+ return ds
}
diff --git a/internal/gatewayapi/route_test.go b/internal/gatewayapi/route_test.go
new file mode 100644
index 00000000000..dd850f29049
--- /dev/null
+++ b/internal/gatewayapi/route_test.go
@@ -0,0 +1,179 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package gatewayapi
+
+import (
+ "fmt"
+ "testing"
+
+ corev1 "k8s.io/api/core/v1"
+ discoveryv1 "k8s.io/api/discovery/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/utils/ptr"
+
+ "github.com/envoyproxy/gateway/internal/ir"
+)
+
+func TestGetIREndpointsFromEndpointSlices(t *testing.T) {
+ tests := []struct {
+ name string
+ endpointSlices []*discoveryv1.EndpointSlice
+ portName string
+ portProtocol corev1.Protocol
+ expectedEndpoints int
+ expectedAddrType ir.DestinationAddressType
+ }{
+ {
+ name: "All IP endpoints",
+ endpointSlices: []*discoveryv1.EndpointSlice{
+ {
+ ObjectMeta: metav1.ObjectMeta{Name: "slice1"},
+ AddressType: discoveryv1.AddressTypeIPv4,
+ Endpoints: []discoveryv1.Endpoint{
+ {Addresses: []string{"192.0.2.1"}},
+ {Addresses: []string{"192.0.2.2"}},
+ },
+ Ports: []discoveryv1.EndpointPort{
+ {Name: ptr.To("http"), Port: ptr.To(int32(80)), Protocol: ptr.To(corev1.ProtocolTCP)},
+ },
+ },
+ {
+ ObjectMeta: metav1.ObjectMeta{Name: "slice2"},
+ AddressType: discoveryv1.AddressTypeIPv6,
+ Endpoints: []discoveryv1.Endpoint{
+ {Addresses: []string{"2001:db8::1"}},
+ },
+ Ports: []discoveryv1.EndpointPort{
+ {Name: ptr.To("http"), Port: ptr.To(int32(80)), Protocol: ptr.To(corev1.ProtocolTCP)},
+ },
+ },
+ },
+ portName: "http",
+ portProtocol: corev1.ProtocolTCP,
+ expectedEndpoints: 3,
+ expectedAddrType: ir.IP,
+ },
+ {
+ name: "Mixed IP and FQDN endpoints",
+ endpointSlices: []*discoveryv1.EndpointSlice{
+ {
+ ObjectMeta: metav1.ObjectMeta{Name: "slice1"},
+ AddressType: discoveryv1.AddressTypeIPv4,
+ Endpoints: []discoveryv1.Endpoint{
+ {Addresses: []string{"192.0.2.1"}},
+ },
+ Ports: []discoveryv1.EndpointPort{
+ {Name: ptr.To("http"), Port: ptr.To(int32(80)), Protocol: ptr.To(corev1.ProtocolTCP)},
+ },
+ },
+ {
+ ObjectMeta: metav1.ObjectMeta{Name: "slice2"},
+ AddressType: discoveryv1.AddressTypeFQDN,
+ Endpoints: []discoveryv1.Endpoint{
+ {Addresses: []string{"example.com"}},
+ },
+ Ports: []discoveryv1.EndpointPort{
+ {Name: ptr.To("http"), Port: ptr.To(int32(80)), Protocol: ptr.To(corev1.ProtocolTCP)},
+ },
+ },
+ },
+ portName: "http",
+ portProtocol: corev1.ProtocolTCP,
+ expectedEndpoints: 2,
+ expectedAddrType: ir.MIXED,
+ },
+ {
+ name: "Dual-stack IP endpoints",
+ endpointSlices: []*discoveryv1.EndpointSlice{
+ {
+ ObjectMeta: metav1.ObjectMeta{Name: "slice1-ipv4"},
+ AddressType: discoveryv1.AddressTypeIPv4,
+ Endpoints: []discoveryv1.Endpoint{
+ {Addresses: []string{"192.0.2.1"}},
+ {Addresses: []string{"192.0.2.2"}},
+ },
+ Ports: []discoveryv1.EndpointPort{
+ {Name: ptr.To("http"), Port: ptr.To(int32(80)), Protocol: ptr.To(corev1.ProtocolTCP)},
+ },
+ },
+ {
+ ObjectMeta: metav1.ObjectMeta{Name: "slice2-ipv6"},
+ AddressType: discoveryv1.AddressTypeIPv6,
+ Endpoints: []discoveryv1.Endpoint{
+ {Addresses: []string{"2001:db8::1"}},
+ {Addresses: []string{"2001:db8::2"}},
+ },
+ Ports: []discoveryv1.EndpointPort{
+ {Name: ptr.To("http"), Port: ptr.To(int32(80)), Protocol: ptr.To(corev1.ProtocolTCP)},
+ },
+ },
+ },
+ portName: "http",
+ portProtocol: corev1.ProtocolTCP,
+ expectedEndpoints: 4,
+ expectedAddrType: ir.IP,
+ },
+ {
+ name: "Dual-stack with FQDN",
+ endpointSlices: []*discoveryv1.EndpointSlice{
+ {
+ ObjectMeta: metav1.ObjectMeta{Name: "slice1-ipv4"},
+ AddressType: discoveryv1.AddressTypeIPv4,
+ Endpoints: []discoveryv1.Endpoint{
+ {Addresses: []string{"192.0.2.1"}},
+ },
+ Ports: []discoveryv1.EndpointPort{
+ {Name: ptr.To("http"), Port: ptr.To(int32(80)), Protocol: ptr.To(corev1.ProtocolTCP)},
+ },
+ },
+ {
+ ObjectMeta: metav1.ObjectMeta{Name: "slice2-ipv6"},
+ AddressType: discoveryv1.AddressTypeIPv6,
+ Endpoints: []discoveryv1.Endpoint{
+ {Addresses: []string{"2001:db8::1"}},
+ },
+ Ports: []discoveryv1.EndpointPort{
+ {Name: ptr.To("http"), Port: ptr.To(int32(80)), Protocol: ptr.To(corev1.ProtocolTCP)},
+ },
+ },
+ {
+ ObjectMeta: metav1.ObjectMeta{Name: "slice3-fqdn"},
+ AddressType: discoveryv1.AddressTypeFQDN,
+ Endpoints: []discoveryv1.Endpoint{
+ {Addresses: []string{"example.com"}},
+ },
+ Ports: []discoveryv1.EndpointPort{
+ {Name: ptr.To("http"), Port: ptr.To(int32(80)), Protocol: ptr.To(corev1.ProtocolTCP)},
+ },
+ },
+ },
+ portName: "http",
+ portProtocol: corev1.ProtocolTCP,
+ expectedEndpoints: 3,
+ expectedAddrType: ir.MIXED,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ endpoints, addrType := getIREndpointsFromEndpointSlices(tt.endpointSlices, tt.portName, tt.portProtocol)
+
+ fmt.Printf("Test case: %s\n", tt.name)
+ fmt.Printf("Number of endpoints: %d\n", len(endpoints))
+ fmt.Printf("Address type: %v\n", *addrType)
+
+ fmt.Println("Actual endpoints:")
+ for i, endpoint := range endpoints {
+ fmt.Printf(" Endpoint %d:\n", i+1)
+ fmt.Printf(" Address: %s\n", endpoint.Host)
+ fmt.Printf(" Port: %d\n", endpoint.Port)
+
+ }
+
+ fmt.Println()
+ })
+ }
+}
diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go
index 8b9b57fc839..62975892918 100644
--- a/internal/gatewayapi/runner/runner.go
+++ b/internal/gatewayapi/runner/runner.go
@@ -8,9 +8,7 @@ package runner
import (
"context"
"crypto/tls"
- "crypto/x509"
"encoding/json"
- "errors"
"fmt"
"os"
"reflect"
@@ -27,19 +25,33 @@ import (
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/crypto"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
extension "github.com/envoyproxy/gateway/internal/extension/types"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/message"
"github.com/envoyproxy/gateway/internal/utils"
"github.com/envoyproxy/gateway/internal/wasm"
)
const (
- wasmCacheDir = "/var/lib/eg/wasm"
- serveTLSCertFilename = "/certs/tls.crt"
- serveTLSKeyFilename = "/certs/tls.key"
- serveTLSCaFilename = "/certs/ca.crt"
+ wasmCacheDir = "/var/lib/eg/wasm"
+
+ // Default certificates path for envoy-gateway with Kubernetes provider.
+ serveTLSCertFilepath = "/certs/tls.crt"
+ serveTLSKeyFilepath = "/certs/tls.key"
+ serveTLSCaFilepath = "/certs/ca.crt"
+
+ // TODO: Make these path configurable.
+ // Default certificates path for envoy-gateway with Host infrastructure provider.
+ localTLSCertFilepath = "/tmp/envoy-gateway/certs/envoy-gateway/tls.crt"
+ localTLSKeyFilepath = "/tmp/envoy-gateway/certs/envoy-gateway/tls.key"
+ localTLSCaFilepath = "/tmp/envoy-gateway/certs/envoy-gateway/ca.crt"
+
+ hmacSecretName = "envoy-oidc-hmac" // nolint: gosec
+ hmacSecretKey = "hmac-secret"
+ hmacSecretPath = "/tmp/envoy-gateway/certs/envoy-oidc-hmac/hmac-secret" // nolint: gosec
)
type Config struct {
@@ -61,12 +73,6 @@ func New(cfg *Config) *Runner {
}
}
-const (
- // nolint: gosec
- hmacSecretName = "envoy-oidc-hmac"
- hmacSecretKey = "hmac-secret"
-)
-
func (r *Runner) Name() string {
return string(egv1a1.LogComponentGatewayAPIRunner)
}
@@ -85,16 +91,12 @@ func (r *Runner) startWasmCache(ctx context.Context) {
// Start the wasm cache server
// EG reuse the OIDC HMAC secret as a hash salt to generate an unguessable
// downloading path for the Wasm module.
- salt, err := hmac(ctx, r.Namespace)
- if err != nil {
- r.Logger.Error(err, "failed to get hmac secret")
- return
- }
- tlsConfig, err := r.tlsConfig()
+ tlsConfig, salt, err := r.loadTLSConfig(ctx)
if err != nil {
- r.Logger.Error(err, "failed to create tls config")
+ r.Logger.Error(err, "failed to start wasm cache")
return
}
+
// Create the file directory if it does not exist.
if err = fileutils.CreateIfNotExists(wasmCacheDir, true); err != nil {
r.Logger.Error(err, "Failed to create Wasm cache directory")
@@ -115,7 +117,7 @@ func (r *Runner) startWasmCache(ctx context.Context) {
func (r *Runner) subscribeAndTranslate(ctx context.Context) {
message.HandleSubscription(message.Metadata{Runner: string(egv1a1.LogComponentGatewayAPIRunner), Message: "provider-resources"}, r.ProviderResources.GatewayAPIResources.Subscribe(ctx),
- func(update message.Update[string, *gatewayapi.ControllerResources], errChan chan error) {
+ func(update message.Update[string, *resource.ControllerResources], errChan chan error) {
r.Logger.Info("received an update")
val := update.Value
// There is only 1 key which is the controller name
@@ -159,6 +161,7 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
extGKs = append(extGKs, schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind})
}
t.ExtensionGroupKinds = extGKs
+ r.Logger.Info("extension resources", "GVKs count", len(extGKs))
}
// Translate to IR
result, err := t.Translate(resources)
@@ -170,7 +173,7 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
// Publish the IRs.
// Also validate the ir before sending it.
for key, val := range result.InfraIR {
- r.Logger.WithValues("infra-ir", key).Info(val.YAMLString())
+ r.Logger.V(1).WithValues("infra-ir", key).Info(val.JSONString())
if err := val.Validate(); err != nil {
r.Logger.Error(err, "unable to validate infra ir, skipped sending it")
errChan <- err
@@ -181,7 +184,7 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
}
for key, val := range result.XdsIR {
- r.Logger.WithValues("xds-ir", key).Info(val.YAMLString())
+ r.Logger.V(1).WithValues("xds-ir", key).Info(val.JSONString())
if err := val.Validate(); err != nil {
r.Logger.Error(err, "unable to validate xds ir, skipped sending it")
errChan <- err
@@ -227,7 +230,6 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
// their target is not found (not relevant)
for _, backendTLSPolicy := range result.BackendTLSPolicies {
- backendTLSPolicy := backendTLSPolicy
key := utils.NamespacedName(backendTLSPolicy)
if !(reflect.ValueOf(backendTLSPolicy.Status).IsZero()) {
r.ProviderResources.BackendTLSPolicyStatuses.Store(key, &backendTLSPolicy.Status)
@@ -257,15 +259,20 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
delete(statusesToDelete.SecurityPolicyStatusKeys, key)
}
for _, envoyExtensionPolicy := range result.EnvoyExtensionPolicies {
- envoyExtensionPolicy := envoyExtensionPolicy
key := utils.NamespacedName(envoyExtensionPolicy)
if !(reflect.ValueOf(envoyExtensionPolicy.Status).IsZero()) {
r.ProviderResources.EnvoyExtensionPolicyStatuses.Store(key, &envoyExtensionPolicy.Status)
}
delete(statusesToDelete.EnvoyExtensionPolicyStatusKeys, key)
}
+ for _, backend := range result.Backends {
+ key := utils.NamespacedName(backend)
+ if !(reflect.ValueOf(backend.Status).IsZero()) {
+ r.ProviderResources.BackendStatuses.Store(key, &backend.Status)
+ }
+ delete(statusesToDelete.BackendStatusKeys, key)
+ }
for _, extServerPolicy := range result.ExtensionServerPolicies {
- extServerPolicy := extServerPolicy
key := message.NamespacedNameAndGVK{
NamespacedName: utils.NamespacedName(&extServerPolicy),
GroupVersionKind: extServerPolicy.GroupVersionKind(),
@@ -293,6 +300,36 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
r.Logger.Info("shutting down")
}
+func (r *Runner) loadTLSConfig(ctx context.Context) (tlsConfig *tls.Config, salt []byte, err error) {
+ switch {
+ case r.EnvoyGateway.Provider.IsRunningOnKubernetes():
+ salt, err = hmac(ctx, r.Namespace)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to get hmac secret: %w", err)
+ }
+
+ tlsConfig, err = crypto.LoadTLSConfig(serveTLSCertFilepath, serveTLSKeyFilepath, serveTLSCaFilepath)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to create tls config: %w", err)
+ }
+
+ case r.EnvoyGateway.Provider.IsRunningOnHost():
+ salt, err = os.ReadFile(hmacSecretPath)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to get hmac secret: %w", err)
+ }
+
+ tlsConfig, err = crypto.LoadTLSConfig(localTLSCertFilepath, localTLSKeyFilepath, localTLSCaFilepath)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to create tls config: %w", err)
+ }
+
+ default:
+ return nil, nil, fmt.Errorf("no valid tls certificates")
+ }
+ return
+}
+
func unstructuredToPolicyStatus(policyStatus map[string]any) gwapiv1a2.PolicyStatus {
var ret gwapiv1a2.PolicyStatus
// No need to check the json marshal/unmarshal error, the policyStatus was
@@ -325,6 +362,8 @@ type StatusesToDelete struct {
SecurityPolicyStatusKeys map[types.NamespacedName]bool
EnvoyExtensionPolicyStatusKeys map[types.NamespacedName]bool
ExtensionServerPolicyStatusKeys map[message.NamespacedNameAndGVK]bool
+
+ BackendStatusKeys map[types.NamespacedName]bool
}
func (r *Runner) getAllStatuses() *StatusesToDelete {
@@ -343,6 +382,8 @@ func (r *Runner) getAllStatuses() *StatusesToDelete {
BackendTLSPolicyStatusKeys: make(map[types.NamespacedName]bool),
EnvoyExtensionPolicyStatusKeys: make(map[types.NamespacedName]bool),
ExtensionServerPolicyStatusKeys: make(map[message.NamespacedNameAndGVK]bool),
+
+ BackendStatusKeys: make(map[types.NamespacedName]bool),
}
// Get current status keys
@@ -380,6 +421,9 @@ func (r *Runner) getAllStatuses() *StatusesToDelete {
for key := range r.ProviderResources.EnvoyExtensionPolicyStatuses.LoadAll() {
ds.EnvoyExtensionPolicyStatusKeys[key] = true
}
+ for key := range r.ProviderResources.BackendStatuses.LoadAll() {
+ ds.BackendStatusKeys[key] = true
+ }
return ds
}
@@ -433,6 +477,10 @@ func (r *Runner) deleteStatusKeys(ds *StatusesToDelete) {
r.ProviderResources.ExtensionPolicyStatuses.Delete(key)
delete(ds.ExtensionServerPolicyStatusKeys, key)
}
+ for key := range ds.BackendStatusKeys {
+ r.ProviderResources.BackendStatuses.Delete(key)
+ delete(ds.BackendStatusKeys, key)
+ }
}
// deleteAllStatusKeys deletes all status keys stored by the subscriber.
@@ -476,6 +524,9 @@ func (r *Runner) deleteAllStatusKeys() {
for key := range r.ProviderResources.ExtensionPolicyStatuses.LoadAll() {
r.ProviderResources.ExtensionPolicyStatuses.Delete(key)
}
+ for key := range r.ProviderResources.BackendStatuses.LoadAll() {
+ r.ProviderResources.BackendStatuses.Delete(key)
+ }
}
// getIRKeysToDelete returns the list of IR keys to delete
@@ -517,35 +568,3 @@ func hmac(ctx context.Context, namespace string) (hmac []byte, err error) {
}
return
}
-
-func (r *Runner) tlsConfig() (*tls.Config, error) {
- var (
- serverCert tls.Certificate // server's certificate and private key
- caCert []byte // the CA certificate for client verification
- caCertPool *x509.CertPool
- err error
- )
-
- // Load server's certificate and private key
- if serverCert, err = tls.LoadX509KeyPair(serveTLSCertFilename, serveTLSKeyFilename); err != nil {
- return nil, err
- }
-
- // Load client's CA certificate
- if caCert, err = os.ReadFile(serveTLSCaFilename); err != nil {
- return nil, err
- }
-
- caCertPool = x509.NewCertPool()
- if !caCertPool.AppendCertsFromPEM(caCert) {
- return nil, errors.New("failed to parse CA certificate")
- }
-
- // Configure the server to require client certificates
- return &tls.Config{
- Certificates: []tls.Certificate{serverCert},
- ClientAuth: tls.RequireAndVerifyClientCert,
- ClientCAs: caCertPool,
- MinVersion: tls.VersionTLS13,
- }, nil
-}
diff --git a/internal/gatewayapi/runner/runner_test.go b/internal/gatewayapi/runner/runner_test.go
index 5f3bc2a6544..58515da7e16 100644
--- a/internal/gatewayapi/runner/runner_test.go
+++ b/internal/gatewayapi/runner/runner_test.go
@@ -105,7 +105,6 @@ func TestGetIRKeysToDelete(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
assert.ElementsMatch(t, tc.delKeys, getIRKeysToDelete(tc.curKeys, tc.newKeys))
})
@@ -165,6 +164,10 @@ func TestDeleteStatusKeys(t *testing.T) {
Name: "test7",
Namespace: "test-namespace",
},
+ {
+ Name: "test8",
+ Namespace: "test-namespace",
+ },
}
r.ProviderResources.GatewayStatuses.Store(keys[0], &gwapiv1.GatewayStatus{})
@@ -174,6 +177,7 @@ func TestDeleteStatusKeys(t *testing.T) {
r.ProviderResources.TCPRouteStatuses.Store(keys[4], &gwapiv1a2.TCPRouteStatus{})
r.ProviderResources.UDPRouteStatuses.Store(keys[5], &gwapiv1a2.UDPRouteStatus{})
r.ProviderResources.UDPRouteStatuses.Store(keys[6], &gwapiv1a2.UDPRouteStatus{})
+ r.ProviderResources.BackendStatuses.Store(keys[7], &egv1a1.BackendStatus{})
// Checks that the keys are successfully stored to DeletableStatus and watchable maps
ds := r.getAllStatuses()
@@ -185,6 +189,7 @@ func TestDeleteStatusKeys(t *testing.T) {
require.True(t, ds.TCPRouteStatusKeys[keys[4]])
require.True(t, ds.UDPRouteStatusKeys[keys[5]])
require.True(t, ds.UDPRouteStatusKeys[keys[6]])
+ require.True(t, ds.BackendStatusKeys[keys[7]])
require.Equal(t, 1, r.ProviderResources.GatewayStatuses.Len())
require.Equal(t, 1, r.ProviderResources.HTTPRouteStatuses.Len())
@@ -192,6 +197,7 @@ func TestDeleteStatusKeys(t *testing.T) {
require.Equal(t, 1, r.ProviderResources.TLSRouteStatuses.Len())
require.Equal(t, 1, r.ProviderResources.TCPRouteStatuses.Len())
require.Equal(t, 2, r.ProviderResources.UDPRouteStatuses.Len())
+ require.Equal(t, 1, r.ProviderResources.BackendStatuses.Len())
// Delete all keys except the last UDPRouteStatus key
delete(ds.UDPRouteStatusKeys, keys[6])
@@ -203,6 +209,7 @@ func TestDeleteStatusKeys(t *testing.T) {
require.Equal(t, 0, r.ProviderResources.TLSRouteStatuses.Len())
require.Equal(t, 0, r.ProviderResources.TCPRouteStatuses.Len())
require.Equal(t, 1, r.ProviderResources.UDPRouteStatuses.Len())
+ require.Equal(t, 0, r.ProviderResources.BackendStatuses.Len())
}
func TestDeleteAllStatusKeys(t *testing.T) {
@@ -254,6 +261,10 @@ func TestDeleteAllStatusKeys(t *testing.T) {
Name: "test6",
Namespace: "test-namespace",
},
+ {
+ Name: "test7",
+ Namespace: "test-namespace",
+ },
}
r.ProviderResources.GatewayStatuses.Store(keys[0], &gwapiv1.GatewayStatus{})
@@ -262,6 +273,7 @@ func TestDeleteAllStatusKeys(t *testing.T) {
r.ProviderResources.TLSRouteStatuses.Store(keys[3], &gwapiv1a2.TLSRouteStatus{})
r.ProviderResources.TCPRouteStatuses.Store(keys[4], &gwapiv1a2.TCPRouteStatus{})
r.ProviderResources.UDPRouteStatuses.Store(keys[5], &gwapiv1a2.UDPRouteStatus{})
+ r.ProviderResources.BackendStatuses.Store(keys[6], &egv1a1.BackendStatus{})
// Checks that the keys are successfully stored to DeletableStatus and watchable maps
ds := r.getAllStatuses()
@@ -272,6 +284,7 @@ func TestDeleteAllStatusKeys(t *testing.T) {
require.True(t, ds.TLSRouteStatusKeys[keys[3]])
require.True(t, ds.TCPRouteStatusKeys[keys[4]])
require.True(t, ds.UDPRouteStatusKeys[keys[5]])
+ require.True(t, ds.BackendStatusKeys[keys[6]])
require.Equal(t, 1, r.ProviderResources.GatewayStatuses.Len())
require.Equal(t, 1, r.ProviderResources.HTTPRouteStatuses.Len())
@@ -279,6 +292,7 @@ func TestDeleteAllStatusKeys(t *testing.T) {
require.Equal(t, 1, r.ProviderResources.TLSRouteStatuses.Len())
require.Equal(t, 1, r.ProviderResources.TCPRouteStatuses.Len())
require.Equal(t, 1, r.ProviderResources.UDPRouteStatuses.Len())
+ require.Equal(t, 1, r.ProviderResources.BackendStatuses.Len())
// Delete all keys
r.deleteAllStatusKeys()
@@ -288,4 +302,5 @@ func TestDeleteAllStatusKeys(t *testing.T) {
require.Equal(t, 0, r.ProviderResources.TLSRouteStatuses.Len())
require.Equal(t, 0, r.ProviderResources.TCPRouteStatuses.Len())
require.Equal(t, 0, r.ProviderResources.UDPRouteStatuses.Len())
+ require.Equal(t, 0, r.ProviderResources.BackendStatuses.Len())
}
diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go
index 2aec807c7b7..d21f240f1fa 100644
--- a/internal/gatewayapi/securitypolicy.go
+++ b/internal/gatewayapi/securitypolicy.go
@@ -9,6 +9,7 @@ import (
"encoding/json"
"errors"
"fmt"
+ "net"
"net/http"
"net/netip"
"net/url"
@@ -26,6 +27,7 @@ import (
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils"
@@ -46,8 +48,8 @@ const (
func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.SecurityPolicy,
gateways []*GatewayContext,
routes []RouteContext,
- resources *Resources,
- xdsIR XdsIRMap,
+ resources *resource.Resources,
+ xdsIR resource.XdsIRMap,
) []*egv1a1.SecurityPolicy {
var res []*egv1a1.SecurityPolicy
@@ -87,7 +89,7 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security
policyName := utils.NamespacedName(currPolicy)
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes)
for _, currTarget := range targetRefs {
- if currTarget.Kind != KindGateway {
+ if currTarget.Kind != resource.KindGateway {
var (
targetedRoute RouteContext
parentGateways []gwapiv1a2.ParentReference
@@ -114,7 +116,7 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security
// The parent gateways are also used to set the status of the policy.
parentRefs := GetParentReferences(targetedRoute)
for _, p := range parentRefs {
- if p.Kind == nil || *p.Kind == KindGateway {
+ if p.Kind == nil || *p.Kind == resource.KindGateway {
namespace := targetedRoute.GetNamespace()
if p.Namespace != nil {
namespace = string(*p.Namespace)
@@ -165,7 +167,7 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security
policyName := utils.NamespacedName(currPolicy)
targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways)
for _, currTarget := range targetRefs {
- if currTarget.Kind == KindGateway {
+ if currTarget.Kind == resource.KindGateway {
var (
targetedGateway *GatewayContext
resolveErr *status.PolicyResolveError
@@ -248,12 +250,10 @@ func resolveSecurityPolicyGatewayTargetRef(
target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName,
gateways map[types.NamespacedName]*policyGatewayTargetContext,
) (*GatewayContext, *status.PolicyResolveError) {
- targetNs := policy.Namespace
-
// Find the Gateway
key := types.NamespacedName{
Name: string(target.Name),
- Namespace: targetNs,
+ Namespace: policy.Namespace,
}
gateway, ok := gateways[key]
@@ -265,18 +265,6 @@ func resolveSecurityPolicyGatewayTargetRef(
return nil, nil
}
- // Ensure Policy and target are in the same namespace
- if policy.Namespace != targetNs {
- // TODO zhaohuabing use CEL to validate cross-namespace reference
- message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, SecurityPolicy can only target a resource in the same namespace.",
- policy.Namespace, targetNs)
-
- return gateway.GatewayContext, &status.PolicyResolveError{
- Reason: gwapiv1a2.PolicyReasonInvalid,
- Message: message,
- }
- }
-
// Check if another policy targeting the same Gateway exists
if gateway.attached {
message := fmt.Sprintf("Unable to target Gateway %s, another SecurityPolicy has already attached to it",
@@ -300,13 +288,11 @@ func resolveSecurityPolicyRouteTargetRef(
target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName,
routes map[policyTargetRouteKey]*policyRouteTargetContext,
) (RouteContext, *status.PolicyResolveError) {
- targetNs := policy.Namespace
-
// Check if the route exists
key := policyTargetRouteKey{
Kind: string(target.Kind),
Name: string(target.Name),
- Namespace: targetNs,
+ Namespace: policy.Namespace,
}
route, ok := routes[key]
@@ -318,18 +304,6 @@ func resolveSecurityPolicyRouteTargetRef(
return nil, nil
}
- // Ensure Policy and target are in the same namespace
- // TODO zhaohuabing use CEL to validate cross-namespace reference
- if policy.Namespace != targetNs {
- message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, SecurityPolicy can only target a resource in the same namespace.",
- policy.Namespace, targetNs)
-
- return route.RouteContext, &status.PolicyResolveError{
- Reason: gwapiv1a2.PolicyReasonInvalid,
- Message: message,
- }
- }
-
// Check if another policy targeting the same xRoute exists
if route.attached {
message := fmt.Sprintf("Unable to target %s %s, another SecurityPolicy has already attached to it",
@@ -350,13 +324,12 @@ func resolveSecurityPolicyRouteTargetRef(
func (t *Translator) translateSecurityPolicyForRoute(
policy *egv1a1.SecurityPolicy, route RouteContext,
- resources *Resources, xdsIR XdsIRMap,
+ resources *resource.Resources, xdsIR resource.XdsIRMap,
) error {
// Build IR
var (
cors *ir.CORS
jwt *ir.JWT
- oidc *ir.OIDC
basicAuth *ir.BasicAuth
authorization *ir.Authorization
err, errs error
@@ -370,15 +343,6 @@ func (t *Translator) translateSecurityPolicyForRoute(
jwt = t.buildJWT(policy.Spec.JWT)
}
- if policy.Spec.OIDC != nil {
- if oidc, err = t.buildOIDC(
- policy,
- resources); err != nil {
- err = perr.WithMessage(err, "OIDC")
- errs = errors.Join(errs, err)
- }
- }
-
if policy.Spec.BasicAuth != nil {
if basicAuth, err = t.buildBasicAuth(
policy,
@@ -409,12 +373,23 @@ func (t *Translator) translateSecurityPolicyForRoute(
if extAuth, err = t.buildExtAuth(
policy,
resources,
- gtwCtx.envoyProxy,
- ); err != nil {
+ gtwCtx.envoyProxy); err != nil {
err = perr.WithMessage(err, "ExtAuth")
errs = errors.Join(errs, err)
}
}
+
+ var oidc *ir.OIDC
+ if policy.Spec.OIDC != nil {
+ if oidc, err = t.buildOIDC(
+ policy,
+ resources,
+ gtwCtx.envoyProxy); err != nil { // TODO zhaohuabing: Only the last EnvoyProxy is used
+ err = perr.WithMessage(err, "OIDC")
+ errs = errors.Join(errs, err)
+ }
+ }
+
irKey := t.getIRKey(gtwCtx.Gateway)
for _, listener := range parentRefCtx.listeners {
irListener := xdsIR[irKey].GetHTTPListener(irListenerName(listener))
@@ -431,8 +406,8 @@ func (t *Translator) translateSecurityPolicyForRoute(
}
if errs != nil {
// Return a 500 direct response to avoid unauthorized access
- r.DirectResponse = &ir.DirectResponse{
- StatusCode: 500,
+ r.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
}
}
}
@@ -447,8 +422,8 @@ func (t *Translator) translateSecurityPolicyForGateway(
policy *egv1a1.SecurityPolicy,
gateway *GatewayContext,
target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName,
- resources *Resources,
- xdsIR XdsIRMap,
+ resources *resource.Resources,
+ xdsIR resource.XdsIRMap,
) error {
// Build IR
var (
@@ -472,7 +447,8 @@ func (t *Translator) translateSecurityPolicyForGateway(
if policy.Spec.OIDC != nil {
if oidc, err = t.buildOIDC(
policy,
- resources); err != nil {
+ resources,
+ gateway.envoyProxy); err != nil {
err = perr.WithMessage(err, "OIDC")
errs = errors.Join(errs, err)
}
@@ -491,8 +467,7 @@ func (t *Translator) translateSecurityPolicyForGateway(
if extAuth, err = t.buildExtAuth(
policy,
resources,
- gateway.envoyProxy,
- ); err != nil {
+ gateway.envoyProxy); err != nil {
err = perr.WithMessage(err, "ExtAuth")
errs = errors.Join(errs, err)
}
@@ -538,8 +513,8 @@ func (t *Translator) translateSecurityPolicyForGateway(
}
if errs != nil {
// Return a 500 direct response to avoid unauthorized access
- r.DirectResponse = &ir.DirectResponse{
- StatusCode: 500,
+ r.DirectResponse = &ir.CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
}
}
}
@@ -551,7 +526,6 @@ func (t *Translator) buildCORS(cors *egv1a1.CORS) *ir.CORS {
var allowOrigins []*ir.StringMatch
for _, origin := range cors.AllowOrigins {
- origin := origin
if isWildcard(string(origin)) {
regexStr := wildcard2regex(string(origin))
allowOrigins = append(allowOrigins, &ir.StringMatch{
@@ -593,20 +567,31 @@ func (t *Translator) buildJWT(jwt *egv1a1.JWT) *ir.JWT {
func (t *Translator) buildOIDC(
policy *egv1a1.SecurityPolicy,
- resources *Resources,
+ resources *resource.Resources,
+ envoyProxy *egv1a1.EnvoyProxy,
) (*ir.OIDC, error) {
var (
- oidc = policy.Spec.OIDC
- clientSecret *corev1.Secret
- provider *ir.OIDCProvider
- err error
+ oidc = policy.Spec.OIDC
+ provider *ir.OIDCProvider
+ clientSecret *corev1.Secret
+ redirectURL = defaultRedirectURL
+ redirectPath = defaultRedirectPath
+ logoutPath = defaultLogoutPath
+ forwardAccessToken = defaultForwardAccessToken
+ refreshToken = defaultRefreshToken
+ err error
)
+ if provider, err = t.buildOIDCProvider(policy, resources, envoyProxy); err != nil {
+ return nil, err
+ }
+
from := crossNamespaceFrom{
group: egv1a1.GroupName,
- kind: KindSecurityPolicy,
+ kind: resource.KindSecurityPolicy,
namespace: policy.Namespace,
}
+
if clientSecret, err = t.validateSecretRef(
false, from, oidc.ClientSecret, resources); err != nil {
return nil, err
@@ -619,25 +604,8 @@ func (t *Translator) buildOIDC(
clientSecret.Namespace, clientSecret.Name)
}
- // Discover the token and authorization endpoints from the issuer's
- // well-known url if not explicitly specified
- if provider, err = discoverEndpointsFromIssuer(&oidc.Provider); err != nil {
- return nil, err
- }
-
- if err = validateTokenEndpoint(provider.TokenEndpoint); err != nil {
- return nil, err
- }
scopes := appendOpenidScopeIfNotExist(oidc.Scopes)
- var (
- redirectURL = defaultRedirectURL
- redirectPath = defaultRedirectPath
- logoutPath = defaultLogoutPath
- forwardAccessToken = defaultForwardAccessToken
- refreshToken = defaultRefreshToken
- )
-
if oidc.RedirectURL != nil {
path, err := extractRedirectPath(*oidc.RedirectURL)
if err != nil {
@@ -691,10 +659,67 @@ func (t *Translator) buildOIDC(
DefaultRefreshTokenTTL: oidc.DefaultRefreshTokenTTL,
CookieSuffix: suffix,
CookieNameOverrides: policy.Spec.OIDC.CookieNames,
+ CookieDomain: policy.Spec.OIDC.CookieDomain,
HMACSecret: hmacData,
}, nil
}
+func (t *Translator) buildOIDCProvider(policy *egv1a1.SecurityPolicy, resources *resource.Resources, envoyProxy *egv1a1.EnvoyProxy) (*ir.OIDCProvider, error) {
+ var (
+ provider = policy.Spec.OIDC.Provider
+ tokenEndpoint string
+ authorizationEndpoint string
+ protocol ir.AppProtocol
+ rd *ir.RouteDestination
+ traffic *ir.TrafficFeatures
+ err error
+ )
+
+ // Discover the token and authorization endpoints from the issuer's
+ // well-known url if not explicitly specified
+ if provider.TokenEndpoint == nil || provider.AuthorizationEndpoint == nil {
+ tokenEndpoint, authorizationEndpoint, err = fetchEndpointsFromIssuer(provider.Issuer)
+ if err != nil {
+ return nil, fmt.Errorf("error fetching endpoints from issuer: %w", err)
+ }
+ } else {
+ tokenEndpoint = *provider.TokenEndpoint
+ authorizationEndpoint = *provider.AuthorizationEndpoint
+ }
+
+ if err = validateTokenEndpoint(tokenEndpoint); err != nil {
+ return nil, err
+ }
+
+ u, err := url.Parse(tokenEndpoint)
+ if err != nil {
+ return nil, err
+ }
+
+ if u.Scheme == "https" {
+ protocol = ir.HTTPS
+ } else {
+ protocol = ir.HTTP
+ }
+
+ if len(provider.BackendRefs) > 0 {
+ if rd, err = t.translateExtServiceBackendRefs(policy, provider.BackendRefs, protocol, resources, envoyProxy, "oidc", 0); err != nil {
+ return nil, err
+ }
+ }
+
+ if traffic, err = translateTrafficFeatures(provider.BackendSettings); err != nil {
+ return nil, err
+ }
+
+ return &ir.OIDCProvider{
+ Destination: rd,
+ Traffic: traffic,
+ AuthorizationEndpoint: authorizationEndpoint,
+ TokenEndpoint: tokenEndpoint,
+ }, nil
+}
+
func extractRedirectPath(redirectURL string) (string, error) {
schemeDelimiter := strings.Index(redirectURL, "://")
if schemeDelimiter <= 0 {
@@ -739,26 +764,6 @@ type OpenIDConfig struct {
AuthorizationEndpoint string `json:"authorization_endpoint"`
}
-// discoverEndpointsFromIssuer discovers the token and authorization endpoints from the issuer's well-known url
-// return error if failed to fetch the well-known configuration
-func discoverEndpointsFromIssuer(provider *egv1a1.OIDCProvider) (*ir.OIDCProvider, error) {
- if provider.TokenEndpoint == nil || provider.AuthorizationEndpoint == nil {
- tokenEndpoint, authorizationEndpoint, err := fetchEndpointsFromIssuer(provider.Issuer)
- if err != nil {
- return nil, fmt.Errorf("error fetching endpoints from issuer: %w", err)
- }
- return &ir.OIDCProvider{
- TokenEndpoint: tokenEndpoint,
- AuthorizationEndpoint: authorizationEndpoint,
- }, nil
- }
-
- return &ir.OIDCProvider{
- TokenEndpoint: *provider.TokenEndpoint,
- AuthorizationEndpoint: *provider.AuthorizationEndpoint,
- }, nil
-}
-
func fetchEndpointsFromIssuer(issuerURL string) (string, string, error) {
// Fetch the OpenID configuration from the issuer URL
resp, err := http.Get(fmt.Sprintf("%s/.well-known/openid-configuration", issuerURL))
@@ -801,7 +806,7 @@ func validateTokenEndpoint(tokenEndpoint string) error {
func (t *Translator) buildBasicAuth(
policy *egv1a1.SecurityPolicy,
- resources *Resources,
+ resources *resource.Resources,
) (*ir.BasicAuth, error) {
var (
basicAuth = policy.Spec.BasicAuth
@@ -811,7 +816,7 @@ func (t *Translator) buildBasicAuth(
from := crossNamespaceFrom{
group: egv1a1.GroupName,
- kind: KindSecurityPolicy,
+ kind: resource.KindSecurityPolicy,
namespace: policy.Namespace,
}
if usersSecret, err = t.validateSecretRef(
@@ -832,96 +837,135 @@ func (t *Translator) buildBasicAuth(
}, nil
}
-func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Resources, envoyProxy *egv1a1.EnvoyProxy) (*ir.ExtAuth, error) {
+func (t *Translator) buildExtAuth(
+ policy *egv1a1.SecurityPolicy,
+ resources *resource.Resources,
+ envoyProxy *egv1a1.EnvoyProxy,
+) (*ir.ExtAuth, error) {
var (
- http = policy.Spec.ExtAuth.HTTP
- grpc = policy.Spec.ExtAuth.GRPC
- backendRef *gwapiv1.BackendObjectReference
- protocol ir.AppProtocol
- ds *ir.DestinationSetting
- authority string
- err error
+ http = policy.Spec.ExtAuth.HTTP
+ grpc = policy.Spec.ExtAuth.GRPC
+ backendRefs []egv1a1.BackendRef
+ backendSettings *egv1a1.ClusterSettings
+ protocol ir.AppProtocol
+ rd *ir.RouteDestination
+ authority string
+ err error
+ traffic *ir.TrafficFeatures
)
- switch {
// These are sanity checks, they should never happen because the API server
// should have caught them
- case http != nil && grpc != nil:
+ if http == nil && grpc == nil {
+ return nil, errors.New("one of grpc or http must be specified")
+ } else if http != nil && grpc != nil {
return nil, errors.New("only one of grpc or http can be specified")
+ }
+
+ switch {
case http != nil:
- backendRef = http.BackendRef
- if len(http.BackendRefs) != 0 {
- backendRef = egv1a1.ToBackendObjectReference(http.BackendRefs[0])
- }
protocol = ir.HTTP
- case grpc != nil:
- backendRef = grpc.BackendRef
- if len(grpc.BackendRefs) != 0 {
- backendRef = egv1a1.ToBackendObjectReference(grpc.BackendRefs[0])
+ switch {
+ case len(http.BackendRefs) > 0:
+ backendRefs = http.BackendCluster.BackendRefs
+ case http.BackendRef != nil:
+ backendRefs = []egv1a1.BackendRef{
+ {
+ BackendObjectReference: *http.BackendRef,
+ },
+ }
+ default:
+ // This is a sanity check, it should never happen because the API server should have caught it
+ return nil, errors.New("http backend refs must be specified")
}
+ case grpc != nil:
protocol = ir.GRPC
- // These are sanity checks, they should never happen because the API server
- // should have caught them
- default: // http == nil && grpc == nil:
- return nil, errors.New("one of grpc or http must be specified")
+ switch {
+ case len(grpc.BackendCluster.BackendRefs) > 0:
+ backendRefs = grpc.BackendRefs
+ case grpc.BackendRef != nil:
+ backendRefs = []egv1a1.BackendRef{
+ {
+ BackendObjectReference: *grpc.BackendRef,
+ },
+ }
+ default:
+ // This is a sanity check, it should never happen because the API server should have caught it
+ return nil, errors.New("grpc backend refs must be specified")
+ }
}
- if err = t.validateExtServiceBackendReference(backendRef, policy.Namespace, policy.Kind, resources); err != nil {
- return nil, err
- }
- authority = fmt.Sprintf("%s.%s:%d",
- backendRef.Name,
- NamespaceDerefOr(backendRef.Namespace, policy.Namespace),
- *backendRef.Port)
-
- pnn := utils.NamespacedName(policy)
- if ds, err = t.processExtServiceDestination(
- backendRef,
- pnn,
- KindSecurityPolicy,
- protocol,
- resources,
- envoyProxy,
- ); err != nil {
+ if rd, err = t.translateExtServiceBackendRefs(policy, backendRefs, protocol, resources, envoyProxy, "extauth", 0); err != nil {
return nil, err
}
- rd := ir.RouteDestination{
- Name: irExtServiceDestinationName(policy, backendRef),
- Settings: []*ir.DestinationSetting{ds},
+
+ for _, backendRef := range backendRefs {
+ // Authority is the calculated hostname that will be used as the Authority header.
+ // If there are multiple backend referenced, simply use the first one - there are no good answers here.
+ // When translated to XDS, the authority is used on the filter level not on the cluster level.
+ // There's no way to translate to XDS and use a different authority for each backendref
+ if authority == "" {
+ authority = backendRefAuthority(resources, &backendRef.BackendObjectReference, policy)
+ }
}
+ if traffic, err = translateTrafficFeatures(backendSettings); err != nil {
+ return nil, err
+ }
extAuth := &ir.ExtAuth{
Name: irConfigName(policy),
HeadersToExtAuth: policy.Spec.ExtAuth.HeadersToExtAuth,
FailOpen: policy.Spec.ExtAuth.FailOpen,
+ Traffic: traffic,
+ RecomputeRoute: policy.Spec.ExtAuth.RecomputeRoute,
}
if http != nil {
extAuth.HTTP = &ir.HTTPExtAuthService{
- Destination: rd,
+ Destination: *rd,
Authority: authority,
Path: ptr.Deref(http.Path, ""),
HeadersToBackend: http.HeadersToBackend,
}
} else {
extAuth.GRPC = &ir.GRPCExtAuthService{
- Destination: rd,
+ Destination: *rd,
Authority: authority,
}
}
+
+ if policy.Spec.ExtAuth.BodyToExtAuth != nil {
+ extAuth.BodyToExtAuth = &ir.BodyToExtAuth{
+ MaxRequestBytes: policy.Spec.ExtAuth.BodyToExtAuth.MaxRequestBytes,
+ }
+ }
+
return extAuth, nil
}
-func irExtServiceDestinationName(policy *egv1a1.SecurityPolicy, backendRef *gwapiv1.BackendObjectReference) string {
- nn := types.NamespacedName{
- Name: string(backendRef.Name),
- Namespace: NamespaceDerefOr(backendRef.Namespace, policy.Namespace),
+func backendRefAuthority(resources *resource.Resources, backendRef *gwapiv1.BackendObjectReference, policy *egv1a1.SecurityPolicy) string {
+ if backendRef == nil {
+ return ""
}
- return strings.ToLower(fmt.Sprintf(
- "%s/%s",
- irConfigName(policy),
- nn.String()))
+ backendNamespace := NamespaceDerefOr(backendRef.Namespace, policy.Namespace)
+ backendKind := KindDerefOr(backendRef.Kind, resource.KindService)
+ if backendKind == resource.KindBackend {
+ backend := resources.GetBackend(backendNamespace, string(backendRef.Name))
+ if backend != nil {
+ // TODO: exists multi FQDN endpoints?
+ for _, ep := range backend.Spec.Endpoints {
+ if ep.FQDN != nil {
+ return net.JoinHostPort(ep.FQDN.Hostname, strconv.Itoa(int(ep.FQDN.Port)))
+ }
+ }
+ }
+ }
+
+ return net.JoinHostPort(
+ fmt.Sprintf("%s.%s", backendRef.Name, backendNamespace),
+ strconv.Itoa(int(*backendRef.Port)),
+ )
}
func (t *Translator) buildAuthorization(policy *egv1a1.SecurityPolicy) (*ir.Authorization, error) {
@@ -949,6 +993,8 @@ func (t *Translator) buildAuthorization(policy *egv1a1.SecurityPolicy) (*ir.Auth
principal.ClientCIDRs = append(principal.ClientCIDRs, cidrMatch)
}
+ principal.JWT = rule.Principal.JWT
+
var name string
if rule.Name != nil && *rule.Name != "" {
name = *rule.Name
diff --git a/internal/gatewayapi/sort.go b/internal/gatewayapi/sort.go
index c11787a60dc..95643a9e154 100644
--- a/internal/gatewayapi/sort.go
+++ b/internal/gatewayapi/sort.go
@@ -8,6 +8,7 @@ package gatewayapi
import (
"sort"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/ir"
)
@@ -81,7 +82,7 @@ func (x XdsIRRoutes) Less(i, j int) bool {
// sortXdsIR sorts the xdsIR based on the match precedence
// defined in the Gateway API spec.
// https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.HTTPRouteRule
-func sortXdsIRMap(xdsIR XdsIRMap) {
+func sortXdsIRMap(xdsIR resource.XdsIRMap) {
for _, irItem := range xdsIR {
for _, http := range irItem.HTTP {
// descending order
diff --git a/internal/gatewayapi/status/backend.go b/internal/gatewayapi/status/backend.go
index 7b841baaa8a..16c0139cae4 100644
--- a/internal/gatewayapi/status/backend.go
+++ b/internal/gatewayapi/status/backend.go
@@ -31,11 +31,11 @@ func UpdateBackendStatusAcceptedCondition(be *egv1a1.Backend, accepted bool, msg
func computeBackendAcceptedCondition(be *egv1a1.Backend, accepted bool, msg string) metav1.Condition {
switch accepted {
case true:
- return newCondition(string(egv1a1.BackendReasonInvalid), metav1.ConditionTrue,
+ return newCondition(string(egv1a1.BackendReasonAccepted), metav1.ConditionTrue,
string(egv1a1.BackendConditionAccepted),
"The Backend was accepted", time.Now(), be.Generation)
default:
- return newCondition(string(egv1a1.BackendReasonAccepted), metav1.ConditionFalse,
+ return newCondition(string(egv1a1.BackendReasonInvalid), metav1.ConditionFalse,
string(egv1a1.BackendConditionAccepted),
msg, time.Now(), be.Generation)
}
diff --git a/internal/gatewayapi/status/gateway.go b/internal/gatewayapi/status/gateway.go
index f891f8c40af..8bf822479d0 100644
--- a/internal/gatewayapi/status/gateway.go
+++ b/internal/gatewayapi/status/gateway.go
@@ -13,6 +13,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
+ "sigs.k8s.io/controller-runtime/pkg/client"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)
@@ -30,8 +31,8 @@ func UpdateGatewayStatusAcceptedCondition(gw *gwapiv1.Gateway, accepted bool) *g
// UpdateGatewayStatusProgrammedCondition updates the status addresses for the provided gateway
// based on the status IP/Hostname of svc and updates the Programmed condition based on the
-// service and deployment state.
-func UpdateGatewayStatusProgrammedCondition(gw *gwapiv1.Gateway, svc *corev1.Service, deployment *appsv1.Deployment, nodeAddresses ...string) {
+// service and deployment or daemonset state.
+func UpdateGatewayStatusProgrammedCondition(gw *gwapiv1.Gateway, svc *corev1.Service, envoyObj client.Object, nodeAddresses ...string) {
var addresses, hostnames []string
// Update the status addresses field.
if svc != nil {
@@ -98,7 +99,7 @@ func UpdateGatewayStatusProgrammedCondition(gw *gwapiv1.Gateway, svc *corev1.Ser
}
// Update the programmed condition.
- updateGatewayProgrammedCondition(gw, deployment)
+ updateGatewayProgrammedCondition(gw, envoyObj)
}
func SetGatewayListenerStatusCondition(gateway *gwapiv1.Gateway, listenerStatusIdx int,
@@ -132,13 +133,13 @@ func computeGatewayAcceptedCondition(gw *gwapiv1.Gateway, accepted bool) metav1.
const (
messageAddressNotAssigned = "No addresses have been assigned to the Gateway"
messageFmtTooManyAddresses = "Too many addresses (%d) have been assigned to the Gateway, the maximum number of addresses is 16"
- messageNoResources = "Deployment replicas unavailable"
- messageFmtProgrammed = "Address assigned to the Gateway, %d/%d envoy Deployment replicas available"
+ messageNoResources = "Envoy replicas unavailable"
+ messageFmtProgrammed = "Address assigned to the Gateway, %d/%d envoy replicas available"
)
// updateGatewayProgrammedCondition computes the Gateway Programmed status condition.
-// Programmed condition surfaces true when the Envoy Deployment status is ready.
-func updateGatewayProgrammedCondition(gw *gwapiv1.Gateway, deployment *appsv1.Deployment) {
+// Programmed condition surfaces true when the Envoy Deployment or DaemonSet status is ready.
+func updateGatewayProgrammedCondition(gw *gwapiv1.Gateway, envoyObj client.Object) {
if len(gw.Status.Addresses) == 0 {
gw.Status.Conditions = MergeConditions(gw.Status.Conditions,
newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionFalse, string(gwapiv1.GatewayReasonAddressNotAssigned),
@@ -157,17 +158,27 @@ func updateGatewayProgrammedCondition(gw *gwapiv1.Gateway, deployment *appsv1.De
return
}
- // If there are no available replicas for the Envoy Deployment, don't
- // mark the Gateway as ready yet.
-
- if deployment == nil || deployment.Status.AvailableReplicas == 0 {
- gw.Status.Conditions = MergeConditions(gw.Status.Conditions,
- newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionFalse, string(gwapiv1.GatewayReasonNoResources),
- messageNoResources, time.Now(), gw.Generation))
- return
+ // Check for available Envoy replicas and if found mark the gateway as ready.
+ switch obj := envoyObj.(type) {
+ case *appsv1.Deployment:
+ if obj != nil && obj.Status.AvailableReplicas > 0 {
+ gw.Status.Conditions = MergeConditions(gw.Status.Conditions,
+ newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionTrue, string(gwapiv1.GatewayConditionProgrammed),
+ fmt.Sprintf(messageFmtProgrammed, obj.Status.AvailableReplicas, obj.Status.Replicas), time.Now(), gw.Generation))
+ return
+ }
+ case *appsv1.DaemonSet:
+ if obj != nil && obj.Status.NumberAvailable > 0 {
+ gw.Status.Conditions = MergeConditions(gw.Status.Conditions,
+ newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionTrue, string(gwapiv1.GatewayConditionProgrammed),
+ fmt.Sprintf(messageFmtProgrammed, obj.Status.NumberAvailable, obj.Status.CurrentNumberScheduled), time.Now(), gw.Generation))
+ return
+ }
}
+ // If there are no available replicas for the Envoy Deployment or
+ // Envoy DaemonSet, don't mark the Gateway as ready yet.
gw.Status.Conditions = MergeConditions(gw.Status.Conditions,
- newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionTrue, string(gwapiv1.GatewayConditionProgrammed),
- fmt.Sprintf(messageFmtProgrammed, deployment.Status.AvailableReplicas, deployment.Status.Replicas), time.Now(), gw.Generation))
+ newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionFalse, string(gwapiv1.GatewayReasonNoResources),
+ messageNoResources, time.Now(), gw.Generation))
}
diff --git a/internal/gatewayapi/status/gateway_test.go b/internal/gatewayapi/status/gateway_test.go
index 0be99b7d4bf..9f9791ac6a5 100644
--- a/internal/gatewayapi/status/gateway_test.go
+++ b/internal/gatewayapi/status/gateway_test.go
@@ -178,6 +178,70 @@ func TestUpdateGatewayStatusProgrammedCondition(t *testing.T) {
return
}(),
},
+ {
+ name: "LoadBalancer svc with IPv6 ingress ip",
+ args: args{
+ gw: &gwapiv1.Gateway{},
+ svc: &corev1.Service{
+ Spec: corev1.ServiceSpec{
+ Type: corev1.ServiceTypeLoadBalancer,
+ },
+ Status: corev1.ServiceStatus{
+ LoadBalancer: corev1.LoadBalancerStatus{
+ Ingress: []corev1.LoadBalancerIngress{
+ {IP: "2001:db8::1"},
+ },
+ },
+ },
+ },
+ },
+ wantAddresses: []gwapiv1.GatewayStatusAddress{
+ {
+ Type: ptr.To(gwapiv1.IPAddressType),
+ Value: "2001:db8::1",
+ },
+ },
+ },
+ {
+ name: "ClusterIP svc with IPv6",
+ args: args{
+ gw: &gwapiv1.Gateway{},
+ svc: &corev1.Service{
+ Spec: corev1.ServiceSpec{
+ ClusterIPs: []string{"2001:db8::2"},
+ Type: corev1.ServiceTypeClusterIP,
+ },
+ },
+ },
+ wantAddresses: []gwapiv1.GatewayStatusAddress{
+ {
+ Type: ptr.To(gwapiv1.IPAddressType),
+ Value: "2001:db8::2",
+ },
+ },
+ },
+ {
+ name: "Nodeport svc with IPv6 node addresses",
+ args: args{
+ gw: &gwapiv1.Gateway{},
+ nodeAddresses: []string{"2001:db8::3", "2001:db8::4"},
+ svc: &corev1.Service{
+ Spec: corev1.ServiceSpec{
+ Type: corev1.ServiceTypeNodePort,
+ },
+ },
+ },
+ wantAddresses: []gwapiv1.GatewayStatusAddress{
+ {
+ Type: ptr.To(gwapiv1.IPAddressType),
+ Value: "2001:db8::3",
+ },
+ {
+ Type: ptr.To(gwapiv1.IPAddressType),
+ Value: "2001:db8::4",
+ },
+ },
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -250,7 +314,6 @@ func TestUpdateGatewayProgrammedCondition(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
gtw := &gwapiv1.Gateway{}
diff --git a/internal/gatewayapi/status/gatewayclass.go b/internal/gatewayapi/status/gatewayclass.go
index 490fc61b9fe..ee49b49345d 100644
--- a/internal/gatewayapi/status/gatewayclass.go
+++ b/internal/gatewayapi/status/gatewayclass.go
@@ -82,12 +82,19 @@ func getSupportedFeatures(gatewaySuite suite.ConformanceOptions, skippedTests []
ret := sets.New[gwapiv1.SupportedFeature]()
for _, feature := range supportedFeatures.UnsortedList() {
- ret.Insert(gwapiv1.SupportedFeature(feature))
+ ret.Insert(gwapiv1.SupportedFeature{
+ Name: gwapiv1.FeatureName(feature),
+ })
}
- return sets.List(ret)
+
+ var featureList []gwapiv1.SupportedFeature
+ for feature := range ret {
+ featureList = append(featureList, feature)
+ }
+ return featureList
}
-func getUnsupportedFeatures(gatewaySuite suite.ConformanceOptions, skippedTests []suite.ConformanceTest) []features.SupportedFeature {
+func getUnsupportedFeatures(gatewaySuite suite.ConformanceOptions, skippedTests []suite.ConformanceTest) []features.FeatureName {
unsupportedFeatures := gatewaySuite.ExemptFeatures.UnsortedList()
for _, skippedTest := range skippedTests {
diff --git a/internal/gatewayapi/status/gatewayclass_test.go b/internal/gatewayapi/status/gatewayclass_test.go
index f2a9dfa42e1..c9f573c9250 100644
--- a/internal/gatewayapi/status/gatewayclass_test.go
+++ b/internal/gatewayapi/status/gatewayclass_test.go
@@ -80,63 +80,76 @@ func TestGetSupportedFeatures(t *testing.T) {
{
name: "No exempt features",
gatewaySuite: suite.ConformanceOptions{
- SupportedFeatures: sets.New[features.SupportedFeature]("Gateway", "HTTPRoute"),
- ExemptFeatures: sets.New[features.SupportedFeature](),
+ SupportedFeatures: sets.New[features.FeatureName]("Gateway", "HTTPRoute"),
+ ExemptFeatures: sets.New[features.FeatureName](),
+ },
+ expectedResult: []gwapiv1.SupportedFeature{
+ {Name: "Gateway"},
+ {Name: "HTTPRoute"},
},
- expectedResult: []gwapiv1.SupportedFeature{"Gateway", "HTTPRoute"},
},
{
name: "All features exempt",
gatewaySuite: suite.ConformanceOptions{
- SupportedFeatures: sets.New[features.SupportedFeature]("Gateway", "HTTPRoute"),
- ExemptFeatures: sets.New[features.SupportedFeature]("Gateway", "HTTPRoute"),
+ SupportedFeatures: sets.New[features.FeatureName]("Gateway", "HTTPRoute"),
+ ExemptFeatures: sets.New[features.FeatureName]("Gateway", "HTTPRoute"),
},
expectedResult: []gwapiv1.SupportedFeature{},
},
{
name: "Some features exempt",
gatewaySuite: suite.ConformanceOptions{
- SupportedFeatures: sets.New[features.SupportedFeature]("Gateway", "HTTPRoute", "GRPCRoute"),
- ExemptFeatures: sets.New[features.SupportedFeature]("GRPCRoute"),
+ SupportedFeatures: sets.New[features.FeatureName]("Gateway", "HTTPRoute", "GRPCRoute"),
+ ExemptFeatures: sets.New[features.FeatureName]("GRPCRoute"),
+ },
+ expectedResult: []gwapiv1.SupportedFeature{
+ {Name: "Gateway"},
+ {Name: "HTTPRoute"},
},
- expectedResult: []gwapiv1.SupportedFeature{"Gateway", "HTTPRoute"},
},
{
name: "Some features exempt with skipped tests",
gatewaySuite: suite.ConformanceOptions{
- SupportedFeatures: sets.New[features.SupportedFeature]("Gateway", "HTTPRoute", "GRPCRoute"),
- ExemptFeatures: sets.New[features.SupportedFeature]("GRPCRoute"),
+ SupportedFeatures: sets.New[features.FeatureName]("Gateway", "HTTPRoute", "GRPCRoute"),
+ ExemptFeatures: sets.New[features.FeatureName]("GRPCRoute"),
},
skippedTests: []suite.ConformanceTest{
{
- Features: []features.SupportedFeature{"HTTPRoute"},
+ Features: []features.FeatureName{"HTTPRoute"},
},
},
- expectedResult: []gwapiv1.SupportedFeature{"Gateway"},
+ expectedResult: []gwapiv1.SupportedFeature{
+ {Name: "Gateway"},
+ },
},
{
name: "Core features remain supported with skipped extended tests",
gatewaySuite: suite.ConformanceOptions{
- SupportedFeatures: sets.New[features.SupportedFeature]("Gateway", "HTTPRoute", "GatewayHTTPListenerIsolation"),
+ SupportedFeatures: sets.New[features.FeatureName]("Gateway", "HTTPRoute", "GatewayHTTPListenerIsolation"),
},
skippedTests: []suite.ConformanceTest{
{
- Features: []features.SupportedFeature{"Gateway", "GatewayHTTPListenerIsolation", "HTTPRoute"},
+ Features: []features.FeatureName{"Gateway", "GatewayHTTPListenerIsolation", "HTTPRoute"},
},
},
- expectedResult: []gwapiv1.SupportedFeature{"Gateway", "HTTPRoute"},
+ expectedResult: []gwapiv1.SupportedFeature{
+ {Name: "Gateway"},
+ {Name: "HTTPRoute"},
+ },
},
{
name: "Core feature removed when skipping core test",
gatewaySuite: suite.ConformanceOptions{
- SupportedFeatures: sets.New[features.SupportedFeature]("Gateway", "HTTPRoute"),
+ SupportedFeatures: sets.New[features.FeatureName]("Gateway", "HTTPRoute"),
},
skippedTests: []suite.ConformanceTest{
{
- Features: []features.SupportedFeature{"HTTPRoute"},
+ Features: []features.FeatureName{"HTTPRoute"},
},
},
- expectedResult: []gwapiv1.SupportedFeature{"Gateway"},
+ expectedResult: []gwapiv1.SupportedFeature{
+ {Name: "Gateway"},
+ },
},
}
diff --git a/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml b/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml
index 643df05037b..d942bf363a4 100644
--- a/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml
+++ b/internal/gatewayapi/testdata/backend-invalid-feature-disabled.out.yaml
@@ -17,7 +17,7 @@ backends:
Gateway Config
reason: Accepted
status: "False"
- type: Accepted
+ type: Invalid
envoyExtensionPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyExtensionPolicy
@@ -168,13 +168,8 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
- envoyExtensions: {}
hostname: '*'
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml b/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml
index e917d9cb2b8..0c022cc4cae 100644
--- a/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml
+++ b/internal/gatewayapi/testdata/backend-invalid-hostname-address.out.yaml
@@ -16,7 +16,7 @@ backends:
message: 'The Backend was not accepted: hostname *.foo.com is not a valid FQDN'
reason: Accepted
status: "False"
- type: Accepted
+ type: Invalid
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -35,7 +35,7 @@ backends:
with at least two segments separated by dots'
reason: Accepted
status: "False"
- type: Accepted
+ type: Invalid
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -54,7 +54,7 @@ backends:
range is not supported'
reason: Accepted
status: "False"
- type: Accepted
+ type: Invalid
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -72,6 +72,6 @@ backends:
message: 'The Backend was not accepted: IP address example.com is invalid'
reason: Accepted
status: "False"
- type: Accepted
+ type: Invalid
infraIR: {}
xdsIR: {}
diff --git a/internal/gatewayapi/testdata/backend-with-fallback.in.yaml b/internal/gatewayapi/testdata/backend-with-fallback.in.yaml
new file mode 100644
index 00000000000..667a75a6557
--- /dev/null
+++ b/internal/gatewayapi/testdata/backend-with-fallback.in.yaml
@@ -0,0 +1,58 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-1
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-2
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-1
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-2
+ namespace: default
+ spec:
+ fallback: true
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3001
diff --git a/internal/gatewayapi/testdata/backend-with-fallback.out.yaml b/internal/gatewayapi/testdata/backend-with-fallback.out.yaml
new file mode 100644
index 00000000000..74bd61795fe
--- /dev/null
+++ b/internal/gatewayapi/testdata/backend-with-fallback.out.yaml
@@ -0,0 +1,180 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-1
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-2
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3001
+ fallback: true
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-1
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-2
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3001
+ priority: 1
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-across-ns.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-across-ns.in.yaml
index e87b3ad1cb9..efd69116641 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-across-ns.in.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-across-ns.in.yaml
@@ -123,7 +123,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
caCertificateRefs:
- name: ca-cmap
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-across-ns.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-across-ns.out.yaml
index fde390c7efe..ae77deb8c62 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-across-ns.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-across-ns.out.yaml
@@ -10,7 +10,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
caCertificateRefs:
- group: ""
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.in.yaml
index b701ad9800f..fd4caad15e4 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.in.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.in.yaml
@@ -108,7 +108,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
caCertificateRefs:
- name: ca-secret
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.out.yaml
index 0e86f25e41f..cd7e70d8bfa 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.out.yaml
@@ -10,7 +10,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
caCertificateRefs:
- group: ""
@@ -156,6 +156,7 @@ xdsIR:
port: 8080
protocol: HTTP
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls/backends-ca
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-ca-only.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-ca-only.in.yaml
index cc6c0f17c8f..2b6701762f7 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-ca-only.in.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-ca-only.in.yaml
@@ -123,7 +123,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
caCertificateRefs:
- name: ca-cmap
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml
index e3354747d5e..a89dc859cdd 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml
@@ -10,7 +10,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
caCertificateRefs:
- group: ""
@@ -156,6 +156,7 @@ xdsIR:
port: 8080
protocol: HTTP
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls/backends-ca
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.in.yaml
index a86b1a25930..2fd3adc48e7 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.in.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.in.yaml
@@ -167,7 +167,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
- group: gateway.envoyproxy.io
kind: Backend
name: backend-ip-tls
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml
index 6f82b206f7c..bbea6c79f5f 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml
@@ -10,7 +10,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
- group: gateway.envoyproxy.io
kind: Backend
name: backend-ip-tls
@@ -62,7 +62,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -290,6 +290,7 @@ xdsIR:
port: 8080
protocol: HTTP
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls/default-ca
@@ -300,6 +301,7 @@ xdsIR:
- host: 2.2.2.2
port: 3443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls/default-ca
@@ -345,6 +347,7 @@ xdsIR:
port: 8080
protocol: HTTP
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls/default-ca
@@ -355,6 +358,7 @@ xdsIR:
- host: 2.2.2.2
port: 3443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls/default-ca
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml
index a92a6be6023..10ac7095127 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml
@@ -33,7 +33,11 @@ httpRoutes:
- name: http-backend
namespace: default
port: 8080
- - name: backend-ip-tls
+ - name: backend-ip-tls-1
+ namespace: default
+ kind: Backend
+ group: gateway.envoyproxy.io
+ - name: backend-ip-tls-2
namespace: default
kind: Backend
group: gateway.envoyproxy.io
@@ -130,7 +134,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
caCertificateRefs:
- name: ca-cmap
@@ -140,13 +144,30 @@ backendTLSPolicies:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: BackendTLSPolicy
metadata:
- name: policy-btls-backend-ip
+ name: policy-btls-backend-ip-1
+ namespace: default
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls-1
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: ip-backend
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-backend-ip-2
namespace: default
spec:
targetRefs:
- group: gateway.envoyproxy.io
kind: Backend
- name: backend-ip-tls
+ name: backend-ip-tls-2
+ sectionName: 3443
validation:
caCertificateRefs:
- name: ca-cmap
@@ -157,10 +178,20 @@ backends:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
- name: backend-ip-tls
+ name: backend-ip-tls-1
namespace: default
spec:
endpoints:
- ip:
address: 2.2.2.2
port: 3443
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip-tls-2
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 3.3.3.3
+ port: 3443
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
index cf416e9726f..0fbf1d8d411 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml
@@ -10,7 +10,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
caCertificateRefs:
- group: ""
@@ -34,13 +34,13 @@ backendTLSPolicies:
kind: BackendTLSPolicy
metadata:
creationTimestamp: null
- name: policy-btls-backend-ip
+ name: policy-btls-backend-ip-1
namespace: default
spec:
targetRefs:
- group: gateway.envoyproxy.io
kind: Backend
- name: backend-ip-tls
+ name: backend-ip-tls-1
validation:
caCertificateRefs:
- group: ""
@@ -60,12 +60,32 @@ backendTLSPolicies:
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-backend-ip-2
+ namespace: default
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls-2
+ sectionName: "3443"
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: ip-backend
+ status:
+ ancestors: null
backends:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
creationTimestamp: null
- name: backend-ip-tls
+ name: backend-ip-tls-1
namespace: default
spec:
endpoints:
@@ -78,7 +98,25 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip-tls-2
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 3.3.3.3
+ port: 3443
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -139,7 +177,11 @@ httpRoutes:
port: 8080
- group: gateway.envoyproxy.io
kind: Backend
- name: backend-ip-tls
+ name: backend-ip-tls-1
+ namespace: default
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls-2
namespace: default
matches:
- path:
@@ -209,6 +251,7 @@ xdsIR:
port: 8080
protocol: HTTP
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls/default-ca
@@ -219,11 +262,17 @@ xdsIR:
- host: 2.2.2.2
port: 3443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
- name: policy-btls-backend-ip/default-ca
+ name: policy-btls-backend-ip-1/default-ca
sni: ip-backend
weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 3.3.3.3
+ port: 3443
+ weight: 1
hostname: '*'
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml
index 7abc20d19c1..a5484a20358 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml
@@ -105,7 +105,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
caCertificateRefs:
- name: no-ca-cmap
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml
index 100efbcab4f..c4436b7f6cc 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml
@@ -10,7 +10,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
caCertificateRefs:
- group: ""
@@ -147,15 +147,8 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-btls/rule/0
- settings:
- - addressType: IP
- endpoints:
- - host: 10.244.0.11
- port: 8080
- protocol: HTTP
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-multiple-targets.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-multiple-targets.in.yaml
new file mode 100644
index 00000000000..96a97fcb0ca
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtlspolicy-multiple-targets.in.yaml
@@ -0,0 +1,123 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway-btls
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-btls-1
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-btls
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ type: Exact
+ value: "/exact-1"
+ backendRefs:
+ - name: http-backend
+ namespace: envoy-gateway
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-btls-2
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-btls
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ type: Exact
+ value: "/exact-2"
+ backendRefs:
+ - name: http-backend
+ namespace: envoy-gateway
+ port: 8081
+
+services:
+ - apiVersion: v1
+ kind: Service
+ metadata:
+ name: http-backend
+ namespace: envoy-gateway
+ spec:
+ clusterIP: 10.11.12.13
+ ports:
+ - port: 8080
+ name: http1
+ protocol: TCP
+ targetPort: 8080
+ - port: 8081
+ name: http2
+ protocol: TCP
+ targetPort: 8081
+
+configMaps:
+ - apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: ca-cmap
+ namespace: envoy-gateway
+ data:
+ ca.crt: |
+ -----BEGIN CERTIFICATE-----
+ MIIDJzCCAg+gAwIBAgIUAl6UKIuKmzte81cllz5PfdN2IlIwDQYJKoZIhvcNAQEL
+ BQAwIzEQMA4GA1UEAwwHbXljaWVudDEPMA0GA1UECgwGa3ViZWRiMB4XDTIzMTAw
+ MjA1NDE1N1oXDTI0MTAwMTA1NDE1N1owIzEQMA4GA1UEAwwHbXljaWVudDEPMA0G
+ A1UECgwGa3ViZWRiMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSTc
+ 1yj8HW62nynkFbXo4VXKv2jC0PM7dPVky87FweZcTKLoWQVPQE2p2kLDK6OEszmM
+ yyr+xxWtyiveremrWqnKkNTYhLfYPhgQkczib7eUalmFjUbhWdLvHakbEgCodn3b
+ kz57mInX2VpiDOKg4kyHfiuXWpiBqrCx0KNLpxo3DEQcFcsQTeTHzh4752GV04RU
+ Ti/GEWyzIsl4Rg7tGtAwmcIPgUNUfY2Q390FGqdH4ahn+mw/6aFbW31W63d9YJVq
+ ioyOVcaMIpM5B/c7Qc8SuhCI1YGhUyg4cRHLEw5VtikioyE3X04kna3jQAj54YbR
+ bpEhc35apKLB21HOUQIDAQABo1MwUTAdBgNVHQ4EFgQUyvl0VI5vJVSuYFXu7B48
+ 6PbMEAowHwYDVR0jBBgwFoAUyvl0VI5vJVSuYFXu7B486PbMEAowDwYDVR0TAQH/
+ BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAMLxrgFVMuNRq2wAwcBt7SnNR5Cfz
+ 2MvXq5EUmuawIUi9kaYjwdViDREGSjk7JW17vl576HjDkdfRwi4E28SydRInZf6J
+ i8HZcZ7caH6DxR335fgHVzLi5NiTce/OjNBQzQ2MJXVDd8DBmG5fyatJiOJQ4bWE
+ A7FlP0RdP3CO3GWE0M5iXOB2m1qWkE2eyO4UHvwTqNQLdrdAXgDQlbam9e4BG3Gg
+ d/6thAkWDbt/QNT+EJHDCvhDRKh1RuGHyg+Y+/nebTWWrFWsktRrbOoHCZiCpXI1
+ 3eXE6nt0YkgtDxG22KqnhpAg9gUSs2hlhoxyvkzyF0mu6NhPlwAgnq7+/Q==
+ -----END CERTIFICATE-----
+backendTLSPolicies:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: ""
+ kind: Service
+ name: http-backend
+ sectionName: http1
+ - group: ""
+ kind: Service
+ name: http-backend
+ sectionName: http2
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ""
+ kind: ConfigMap
+ hostname: example.com
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-multiple-targets.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-multiple-targets.out.yaml
new file mode 100644
index 00000000000..75f11c18849
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtlspolicy-multiple-targets.out.yaml
@@ -0,0 +1,239 @@
+backendTLSPolicies:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: ""
+ kind: Service
+ name: http-backend
+ sectionName: http1
+ - group: ""
+ kind: Service
+ name: http-backend
+ sectionName: http2
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: example.com
+ status:
+ ancestors:
+ - ancestorRef:
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-btls
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-btls-1
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: http-backend
+ namespace: envoy-gateway
+ port: 8080
+ matches:
+ - path:
+ type: Exact
+ value: /exact-1
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-btls-2
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: http-backend
+ namespace: envoy-gateway
+ port: 8081
+ matches:
+ - path:
+ type: Exact
+ value: /exact-2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-btls:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-btls/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-btls
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-btls
+xdsIR:
+ envoy-gateway/gateway-btls:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-btls/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/envoy-gateway/httproute-btls-1/rule/0
+ settings:
+ - protocol: HTTP
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls/envoy-gateway-ca
+ sni: example.com
+ weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-btls-1
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-btls-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ exact: /exact-1
+ name: ""
+ - destination:
+ name: httproute/envoy-gateway/httproute-btls-2/rule/0
+ settings:
+ - protocol: HTTP
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls/envoy-gateway-ca
+ sni: example.com
+ weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-btls-2
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-btls-2/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ exact: /exact-2
+ name: ""
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.in.yaml
index 3b20aa31ee5..520065b82a4 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.in.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.in.yaml
@@ -98,7 +98,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
wellKnownCACertificates: System
hostname: example.com
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml
index 8eccc22950c..dbe5fcb90f2 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml
@@ -10,7 +10,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "8080"
+ sectionName: http
validation:
hostname: example.com
wellKnownCACertificates: System
@@ -153,6 +153,7 @@ xdsIR:
port: 8080
protocol: HTTP
tls:
+ alpnProtocols: null
sni: example.com
useSystemTrustStore: true
weight: 1
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-out-of-range-error.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-out-of-range-error.out.yaml
index 67e8dd5620c..bb171e01da7 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-out-of-range-error.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-out-of-range-error.out.yaml
@@ -316,6 +316,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-with-invalid-value.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-with-invalid-value.out.yaml
index cb0037b75bf..654c9bdab4a 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-with-invalid-value.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-with-invalid-value.out.yaml
@@ -316,6 +316,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml
index 1a054712d80..7c63ff375ed 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml
@@ -555,11 +555,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
@@ -593,11 +589,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: grpcroute/envoy-gateway/grpcroute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
headerMatches:
- distinct: false
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml
index 969005436cb..2b49ea23741 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml
@@ -335,6 +335,8 @@ xdsIR:
port: 8080
protocol: GRPC
weight: 1
+ directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: true
metadata:
@@ -371,6 +373,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
@@ -391,6 +395,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.in.yaml
new file mode 100644
index 00000000000..f1d48c4d31d
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.in.yaml
@@ -0,0 +1,127 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-2
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-2
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-2
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/v2"
+ backendRefs:
+ - name: service-2
+ port: 8080
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-3
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/v3"
+ backendRefs:
+ - name: service-3
+ port: 8080
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-route-1
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ dns:
+ dnsRefreshRate: "1s"
+ respectDnsTtl: true
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-route-2
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-2
+ dns:
+ dnsRefreshRate: "5s"
+ respectDnsTtl: false
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: policy-for-all-routes-in-gateway-1
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ dns:
+ dnsRefreshRate: "10s"
+ respectDnsTtl: true
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml
new file mode 100644
index 00000000000..12bbf12dbe7
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml
@@ -0,0 +1,427 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-route-1
+ namespace: default
+ spec:
+ dns:
+ dnsRefreshRate: 1s
+ respectDnsTtl: true
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-route-2
+ namespace: default
+ spec:
+ dns:
+ dnsRefreshRate: 5s
+ respectDnsTtl: false
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-2
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-all-routes-in-gateway-1
+ namespace: envoy-gateway
+ spec:
+ dns:
+ dnsRefreshRate: 10s
+ respectDnsTtl: true
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-2
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ matches:
+ - path:
+ value: /v2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-3
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-3
+ port: 8080
+ matches:
+ - path:
+ value: /v3
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+ envoy-gateway/gateway-2:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-2/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-2
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-2
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-3/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-3
+ namespace: default
+ name: httproute/default/httproute-3/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /v3
+ traffic:
+ dns:
+ dnsRefreshRate: 10s
+ respectDnsTtl: true
+ envoy-gateway/gateway-2:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-2/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /v2
+ traffic:
+ dns:
+ dnsRefreshRate: 5s
+ respectDnsTtl: false
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ traffic:
+ dns:
+ dnsRefreshRate: 1s
+ respectDnsTtl: true
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml
index 5cb832646b3..fc324a70a9b 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml
@@ -42,6 +42,34 @@ grpcRoutes:
- backendRefs:
- name: service-1
port: 8080
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ namespace: default
+ name: grpcroute-3
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-3
+ port: 8080
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ namespace: default
+ name: grpcroute-2
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-2
+ port: 8080
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
@@ -100,6 +128,25 @@ httpRoutes:
backendRefs:
- name: service-3
port: 8080
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-4
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-2
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/v2"
+ backendRefs:
+ - name: service-2
+ port: 8080
backendTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
@@ -169,6 +216,29 @@ backendTrafficPolicies:
consecutiveGatewayErrors: 0
consecutiveLocalOriginFailures: 5
splitExternalLocalOriginErrors: false
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-route-4
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-4
+ healthCheck:
+ active:
+ timeout: "1s"
+ interval: "5s"
+ unhealthyThreshold: 3
+ healthyThreshold: 3
+ type: HTTP
+ http:
+ path: "/healthz"
+ method: "GET"
+ expectedResponse:
+ type: Text
+ text: pong
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
@@ -233,3 +303,40 @@ backendTrafficPolicies:
consecutiveGatewayErrors: 0
consecutiveLocalOriginFailures: 5
splitExternalLocalOriginErrors: false
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-grpc-route
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ name: grpcroute-2
+ healthCheck:
+ active:
+ timeout: 1s
+ interval: 3s
+ unhealthyThreshold: 3
+ healthyThreshold: 1
+ type: GRPC
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-grpc-route-3
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ name: grpcroute-3
+ healthCheck:
+ active:
+ timeout: 1s
+ interval: 3s
+ unhealthyThreshold: 3
+ healthyThreshold: 1
+ type: GRPC
+ grpc:
+ service: foo-service
+
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
index 447a7df485e..4f964492673 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
@@ -49,6 +49,45 @@ backendTrafficPolicies:
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-route-4
+ namespace: default
+ spec:
+ healthCheck:
+ active:
+ healthyThreshold: 3
+ http:
+ expectedResponse:
+ text: pong
+ type: Text
+ method: GET
+ path: /healthz
+ interval: 5s
+ timeout: 1s
+ type: HTTP
+ unhealthyThreshold: 3
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-4
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
@@ -145,6 +184,74 @@ backendTrafficPolicies:
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-grpc-route
+ namespace: default
+ spec:
+ healthCheck:
+ active:
+ healthyThreshold: 1
+ interval: 3s
+ timeout: 1s
+ type: GRPC
+ unhealthyThreshold: 3
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ name: grpcroute-2
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-grpc-route-3
+ namespace: default
+ spec:
+ healthCheck:
+ active:
+ grpc:
+ service: foo-service
+ healthyThreshold: 1
+ interval: 3s
+ timeout: 1s
+ type: GRPC
+ unhealthyThreshold: 3
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ name: grpcroute-3
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
@@ -193,6 +300,12 @@ backendTrafficPolicies:
reason: Accepted
status: "True"
type: Accepted
+ - lastTransitionTime: null
+ message: 'This policy is being overridden by other backendTrafficPolicies
+ for these routes: [default/grpcroute-2 default/grpcroute-3]'
+ reason: Overridden
+ status: "True"
+ type: Overridden
controllerName: gateway.envoyproxy.io/gatewayclass-controller
gateways:
- apiVersion: gateway.networking.k8s.io/v1
@@ -212,7 +325,7 @@ gateways:
protocol: HTTP
status:
listeners:
- - attachedRoutes: 1
+ - attachedRoutes: 3
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
@@ -252,7 +365,7 @@ gateways:
protocol: HTTP
status:
listeners:
- - attachedRoutes: 3
+ - attachedRoutes: 4
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
@@ -309,6 +422,72 @@ grpcRoutes:
name: gateway-1
namespace: envoy-gateway
sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ creationTimestamp: null
+ name: grpcroute-3
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-3
+ port: 8080
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ creationTimestamp: null
+ name: grpcroute-2
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
@@ -424,6 +603,44 @@ httpRoutes:
name: gateway-2
namespace: envoy-gateway
sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-4
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ matches:
+ - path:
+ value: /v2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
infraIR:
envoy-gateway/gateway-1:
proxy:
@@ -516,6 +733,55 @@ xdsIR:
interval: 2s
maxEjectionPercent: 100
splitExternalLocalOriginErrors: false
+ - destination:
+ name: grpcroute/default/grpcroute-3/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ hostname: '*'
+ isHTTP2: true
+ metadata:
+ kind: GRPCRoute
+ name: grpcroute-3
+ namespace: default
+ name: grpcroute/default/grpcroute-3/rule/0/match/-1/*
+ traffic:
+ healthCheck:
+ active:
+ grpc:
+ service: foo-service
+ healthyThreshold: 1
+ interval: 3s
+ timeout: 1s
+ unhealthyThreshold: 3
+ - destination:
+ name: grpcroute/default/grpcroute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ hostname: '*'
+ isHTTP2: true
+ metadata:
+ kind: GRPCRoute
+ name: grpcroute-2
+ namespace: default
+ name: grpcroute/default/grpcroute-2/rule/0/match/-1/*
+ traffic:
+ healthCheck:
+ active:
+ grpc: {}
+ healthyThreshold: 1
+ interval: 3s
+ timeout: 1s
+ unhealthyThreshold: 3
envoy-gateway/gateway-2:
accessLog:
text:
@@ -616,6 +882,41 @@ xdsIR:
interval: 8ms
maxEjectionPercent: 11
splitExternalLocalOriginErrors: false
+ - destination:
+ name: httproute/default/httproute-4/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-4
+ namespace: default
+ name: httproute/default/httproute-4/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /v2
+ traffic:
+ healthCheck:
+ active:
+ healthyThreshold: 3
+ http:
+ expectedResponse:
+ text: pong
+ expectedStatuses:
+ - 200
+ host: gateway.envoyproxy.io
+ method: GET
+ path: /healthz
+ interval: 5s
+ timeout: 1s
+ unhealthyThreshold: 3
- destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml
new file mode 100644
index 00000000000..f8962194199
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml
@@ -0,0 +1,95 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-2
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+grpcRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ namespace: default
+ name: grpcroute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-2
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+backendTrafficPolicies:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: policy-for-gateway
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ http2:
+ initialStreamWindowSize: 2Mi
+ initialConnectionWindowSize: 1Gi
+ maxConcurrentStreams: 500
+ onInvalidMessage: TerminateConnection
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-route
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ http2:
+ initialStreamWindowSize: 1Mi
+ initialConnectionWindowSize: 500Mi
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml
new file mode 100644
index 00000000000..35dbb164bf1
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml
@@ -0,0 +1,336 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-route
+ namespace: default
+ spec:
+ http2:
+ initialConnectionWindowSize: 500Mi
+ initialStreamWindowSize: 1Mi
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-gateway
+ namespace: envoy-gateway
+ spec:
+ http2:
+ initialConnectionWindowSize: 1Gi
+ initialStreamWindowSize: 2Mi
+ maxConcurrentStreams: 500
+ onInvalidMessage: TerminateConnection
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-2
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ creationTimestamp: null
+ name: grpcroute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+ envoy-gateway/gateway-2:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-2/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-2
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-2
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: true
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: grpcroute/default/grpcroute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ hostname: '*'
+ isHTTP2: true
+ metadata:
+ kind: GRPCRoute
+ name: grpcroute-1
+ namespace: default
+ name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
+ traffic:
+ http2:
+ initialConnectionWindowSize: 2097152
+ initialStreamWindowSize: 1073741824
+ maxConcurrentStreams: 500
+ resetStreamOnError: false
+ envoy-gateway/gateway-2:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-2/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ traffic:
+ http2:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 524288000
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-httproute-timeout.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-httproute-timeout.in.yaml
new file mode 100644
index 00000000000..33ae5c94859
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-httproute-timeout.in.yaml
@@ -0,0 +1,87 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ timeouts:
+ request: 130s
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ timeouts:
+ request: 130s
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route-1
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ useClientProtocol: true
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: policy-for-gateway
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ useClientProtocol: true
+ loadBalancer:
+ type: ConsistentHash
+ consistentHash:
+ type: Cookie
+ cookie:
+ name: "test"
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-httproute-timeout.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-httproute-timeout.out.yaml
new file mode 100644
index 00000000000..c60ae5b2347
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-httproute-timeout.out.yaml
@@ -0,0 +1,275 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route-1
+ namespace: default
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ useClientProtocol: true
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-gateway
+ namespace: envoy-gateway
+ spec:
+ loadBalancer:
+ consistentHash:
+ cookie:
+ name: test
+ type: Cookie
+ type: ConsistentHash
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ useClientProtocol: true
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: 'This policy is being overridden by other backendTrafficPolicies
+ for these routes: [default/httproute-1]'
+ reason: Overridden
+ status: "True"
+ type: Overridden
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ timeouts:
+ request: 130s
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ timeouts:
+ request: 130s
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ timeout: 2m10s
+ traffic: {}
+ useClientProtocol: true
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ timeout: 2m10s
+ traffic:
+ loadBalancer:
+ consistentHash:
+ cookie:
+ name: test
+ useClientProtocol: true
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer-invalid-consistent-hash-table-size.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer-invalid-consistent-hash-table-size.out.yaml
index 05e6140a298..dc2ba7fb3d3 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer-invalid-consistent-hash-table-size.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer-invalid-consistent-hash-table-size.out.yaml
@@ -225,6 +225,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
@@ -245,6 +247,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml
index ebce8acb474..0be116e1ebf 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml
@@ -178,6 +178,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml
index e5298e279a4..21cae9b09f3 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml
@@ -174,6 +174,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml
index 80e55671513..0fd1f442bd8 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml
@@ -181,6 +181,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-distinct-invert.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-distinct-invert.in.yaml
new file mode 100644
index 00000000000..a1ed0f512cc
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-distinct-invert.in.yaml
@@ -0,0 +1,53 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ namespace: default
+ name: grpcroute
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service
+ port: 8080
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: policy-for-gateway
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway
+ rateLimit:
+ type: Global
+ global:
+ rules:
+ - clientSelectors:
+ - headers:
+ - name: x-org-id
+ type: Distinct
+ invert: true
+ limit:
+ requests: 10
+ unit: Hour
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-distinct-invert.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-distinct-invert.out.yaml
new file mode 100644
index 00000000000..d4c68adcb6f
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-distinct-invert.out.yaml
@@ -0,0 +1,160 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-gateway
+ namespace: envoy-gateway
+ spec:
+ rateLimit:
+ global:
+ rules:
+ - clientSelectors:
+ - headers:
+ - invert: true
+ name: x-org-id
+ type: Distinct
+ limit:
+ requests: 10
+ unit: Hour
+ type: Global
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: 'RateLimit: unable to translate rateLimit.Invert is not applicable
+ for distinct header match type.'
+ reason: Invalid
+ status: "False"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ creationTimestamp: null
+ name: grpcroute
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service
+ port: 8080
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Service default/service not found
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway
+xdsIR:
+ envoy-gateway/gateway:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: true
+ metadata:
+ kind: Gateway
+ name: gateway
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: true
+ metadata:
+ kind: GRPCRoute
+ name: grpcroute
+ namespace: default
+ name: grpcroute/default/grpcroute/rule/0/match/-1/*
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml
index 74ced58453e..8b20cbc59c9 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml
@@ -160,6 +160,8 @@ xdsIR:
port: 8080
protocol: GRPC
weight: 1
+ directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: true
metadata:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.in.yaml
index e4f1fc10c64..f536d9a20bc 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.in.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.in.yaml
@@ -83,6 +83,9 @@ backendTrafficPolicies:
value: one
- name: x-org-id
type: Distinct
+ - name: x-org-id
+ value: admin
+ invert: true
limit:
requests: 10
unit: Hour
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml
index 2f7a2d5e8f9..07fa997e109 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml
@@ -52,6 +52,9 @@ backendTrafficPolicies:
value: one
- name: x-org-id
type: Distinct
+ - invert: true
+ name: x-org-id
+ value: admin
limit:
requests: 10
unit: Hour
@@ -306,6 +309,10 @@ xdsIR:
name: x-user-id
- distinct: true
name: x-org-id
+ - distinct: false
+ exact: admin
+ invert: true
+ name: x-org-id
limit:
requests: 10
unit: Hour
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override-invalid-valueref.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override-invalid-valueref.in.yaml
new file mode 100644
index 00000000000..e44a8473d5c
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override-invalid-valueref.in.yaml
@@ -0,0 +1,141 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-2
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+grpcRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ namespace: default
+ name: grpcroute-1
+ spec:
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: default
+ name: gateway-2
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+configMaps:
+ - apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: response-override-config
+ namespace: default
+ data: {}
+backendTrafficPolicies:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-gateway
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ responseOverride:
+ - match:
+ statusCodes:
+ - type: Value
+ value: 404
+ response:
+ contentType: text/plain
+ body:
+ type: Inline
+ inline: "gateway-1 Not Found"
+ - match:
+ statusCodes:
+ - type: Value
+ value: 500
+ - type: Range
+ range:
+ start: 501
+ end: 511
+ response:
+ contentType: application/json
+ body:
+ type: ValueRef
+ valueRef:
+ group: ""
+ kind: ConfigMap
+ name: response-override-config
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-route
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ responseOverride:
+ - match:
+ statusCodes:
+ - value: 404
+ response:
+ contentType: text/plain
+ body:
+ inline: "httproute-1 Not Found"
+ - match:
+ statusCodes:
+ - value: 500
+ - type: Range
+ range:
+ start: 501
+ end: 511
+ response:
+ contentType: application/json
+ body:
+ type: ValueRef
+ valueRef:
+ group: ""
+ kind: ConfigMap
+ name: response-override-config-1
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override-invalid-valueref.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override-invalid-valueref.out.yaml
new file mode 100644
index 00000000000..c1542d9caec
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override-invalid-valueref.out.yaml
@@ -0,0 +1,371 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-route
+ namespace: default
+ spec:
+ responseOverride:
+ - match:
+ statusCodes:
+ - type: null
+ value: 404
+ response:
+ body:
+ inline: httproute-1 Not Found
+ type: null
+ contentType: text/plain
+ - match:
+ statusCodes:
+ - type: null
+ value: 500
+ - range:
+ end: 511
+ start: 501
+ type: Range
+ response:
+ body:
+ type: ValueRef
+ valueRef:
+ group: ""
+ kind: ConfigMap
+ name: response-override-config-1
+ contentType: application/json
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: 'ResponseOverride: can''t find the referenced configmap response-override-config-1.'
+ reason: Invalid
+ status: "False"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-gateway
+ namespace: default
+ spec:
+ responseOverride:
+ - match:
+ statusCodes:
+ - type: Value
+ value: 404
+ response:
+ body:
+ inline: gateway-1 Not Found
+ type: Inline
+ contentType: text/plain
+ - match:
+ statusCodes:
+ - type: Value
+ value: 500
+ - range:
+ end: 511
+ start: 501
+ type: Range
+ response:
+ body:
+ type: ValueRef
+ valueRef:
+ group: ""
+ kind: ConfigMap
+ name: response-override-config
+ contentType: application/json
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: 'ResponseOverride: can''t find the key response.body in the referenced
+ configmap response-override-config.'
+ reason: Invalid
+ status: "False"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-2
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ creationTimestamp: null
+ name: grpcroute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-2
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-2
+ namespace: default
+ sectionName: http
+infraIR:
+ default/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-1
+ default/gateway-2:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-2/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-2
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-2
+xdsIR:
+ default/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: true
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: grpcroute/default/grpcroute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: true
+ metadata:
+ kind: GRPCRoute
+ name: grpcroute-1
+ namespace: default
+ name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
+ default/gateway-2:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-2
+ namespace: default
+ sectionName: http
+ name: default/gateway-2/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override.in.yaml
new file mode 100644
index 00000000000..51dd9fd7114
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override.in.yaml
@@ -0,0 +1,145 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-2
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+grpcRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ namespace: default
+ name: grpcroute-1
+ spec:
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: default
+ name: gateway-2
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+configMaps:
+ - apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: response-override-config
+ namespace: default
+ data:
+ response.body: |
+ {
+ "error": "Internal Server Error"
+ }
+backendTrafficPolicies:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-gateway
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ responseOverride:
+ - match:
+ statusCodes:
+ - type: Value
+ value: 404
+ response:
+ contentType: text/plain
+ body:
+ type: Inline
+ inline: "gateway-1 Not Found"
+ - match:
+ statusCodes:
+ - type: Value
+ value: 500
+ - type: Range
+ range:
+ start: 501
+ end: 511
+ response:
+ contentType: application/json
+ body:
+ type: ValueRef
+ valueRef:
+ group: ""
+ kind: ConfigMap
+ name: response-override-config
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-route
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ responseOverride:
+ - match:
+ statusCodes:
+ - value: 404
+ response:
+ contentType: text/plain
+ body:
+ inline: "httproute-1 Not Found"
+ - match:
+ statusCodes:
+ - value: 500
+ - type: Range
+ range:
+ start: 501
+ end: 511
+ response:
+ contentType: application/json
+ body:
+ type: ValueRef
+ valueRef:
+ group: ""
+ kind: ConfigMap
+ name: response-override-config
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override.out.yaml
new file mode 100644
index 00000000000..568a57af484
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-response-override.out.yaml
@@ -0,0 +1,414 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-route
+ namespace: default
+ spec:
+ responseOverride:
+ - match:
+ statusCodes:
+ - type: null
+ value: 404
+ response:
+ body:
+ inline: httproute-1 Not Found
+ type: null
+ contentType: text/plain
+ - match:
+ statusCodes:
+ - type: null
+ value: 500
+ - range:
+ end: 511
+ start: 501
+ type: Range
+ response:
+ body:
+ type: ValueRef
+ valueRef:
+ group: ""
+ kind: ConfigMap
+ name: response-override-config
+ contentType: application/json
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-gateway
+ namespace: default
+ spec:
+ responseOverride:
+ - match:
+ statusCodes:
+ - type: Value
+ value: 404
+ response:
+ body:
+ inline: gateway-1 Not Found
+ type: Inline
+ contentType: text/plain
+ - match:
+ statusCodes:
+ - type: Value
+ value: 500
+ - range:
+ end: 511
+ start: 501
+ type: Range
+ response:
+ body:
+ type: ValueRef
+ valueRef:
+ group: ""
+ kind: ConfigMap
+ name: response-override-config
+ contentType: application/json
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-2
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ creationTimestamp: null
+ name: grpcroute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-2
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-2
+ namespace: default
+ sectionName: http
+infraIR:
+ default/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-1
+ default/gateway-2:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-2/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-2
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-2
+xdsIR:
+ default/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: true
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: grpcroute/default/grpcroute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ hostname: '*'
+ isHTTP2: true
+ metadata:
+ kind: GRPCRoute
+ name: grpcroute-1
+ namespace: default
+ name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
+ traffic:
+ responseOverride:
+ name: backendtrafficpolicy/default/policy-for-gateway
+ rules:
+ - match:
+ statusCodes:
+ - value: 404
+ name: backendtrafficpolicy/default/policy-for-gateway/responseoverride/rule/0
+ response:
+ body: gateway-1 Not Found
+ contentType: text/plain
+ - match:
+ statusCodes:
+ - value: 500
+ - range:
+ end: 511
+ start: 501
+ name: backendtrafficpolicy/default/policy-for-gateway/responseoverride/rule/1
+ response:
+ body: |
+ {
+ "error": "Internal Server Error"
+ }
+ contentType: application/json
+ default/gateway-2:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-2
+ namespace: default
+ sectionName: http
+ name: default/gateway-2/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ traffic:
+ responseOverride:
+ name: backendtrafficpolicy/default/policy-for-route
+ rules:
+ - match:
+ statusCodes:
+ - value: 404
+ name: backendtrafficpolicy/default/policy-for-route/responseoverride/rule/0
+ response:
+ body: httproute-1 Not Found
+ contentType: text/plain
+ - match:
+ statusCodes:
+ - value: 500
+ - range:
+ end: 511
+ start: 501
+ name: backendtrafficpolicy/default/policy-for-route/responseoverride/rule/1
+ response:
+ body: |
+ {
+ "error": "Internal Server Error"
+ }
+ contentType: application/json
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml
index 660c8d7d800..9fa8e7235c9 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml
@@ -309,9 +309,3 @@ xdsIR:
consistentHash:
sourceIP: true
name: udproute/default/udp-app-1
- timeout:
- http:
- connectionIdleTimeout: 16s
- maxConnectionDuration: 17s
- tcp:
- connectTimeout: 15s
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml
index 8f5fcbe4b03..5b1707b6f1a 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml
@@ -382,9 +382,3 @@ xdsIR:
consistentHash:
sourceIP: true
name: udproute/default/udp-app-1
- timeout:
- http:
- connectionIdleTimeout: 16s
- maxConnectionDuration: 17s
- tcp:
- connectTimeout: 15s
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml
index 8ddcdf83cdb..dc80d9e73a8 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml
@@ -151,6 +151,8 @@ xdsIR:
port: 8080
protocol: GRPC
weight: 1
+ directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: true
metadata:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-targetrefs.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-targetrefs.out.yaml
index ea546413a59..72646d946e0 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-targetrefs.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-targetrefs.out.yaml
@@ -252,11 +252,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: grpcroute/envoy-gateway/grpcroute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: true
@@ -292,11 +288,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.in.yaml
index ef8843f70c4..30a9a3133ab 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.in.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.in.yaml
@@ -62,6 +62,8 @@ httpRoutes:
backendRefs:
- name: service-1
port: 8080
+ timeouts:
+ request: 1s
backendTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
@@ -79,6 +81,7 @@ backendTrafficPolicies:
http:
connectionIdleTimeout: 16s
maxConnectionDuration: 17s
+ requestTimeout: 18s
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
@@ -95,3 +98,4 @@ backendTrafficPolicies:
http:
connectionIdleTimeout: 21s
maxConnectionDuration: 22s
+ requestTimeout: 23s
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml
index 5213fc9d6a2..7177bcae009 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml
@@ -14,6 +14,7 @@ backendTrafficPolicies:
http:
connectionIdleTimeout: 21s
maxConnectionDuration: 22s
+ requestTimeout: 23s
tcp:
connectTimeout: 20s
status:
@@ -46,6 +47,7 @@ backendTrafficPolicies:
http:
connectionIdleTimeout: 16s
maxConnectionDuration: 17s
+ requestTimeout: 18s
tcp:
connectTimeout: 15s
status:
@@ -198,6 +200,8 @@ httpRoutes:
matches:
- path:
value: /
+ timeouts:
+ request: 1s
status:
parents:
- conditions:
@@ -289,6 +293,7 @@ xdsIR:
http:
connectionIdleTimeout: 16s
maxConnectionDuration: 17s
+ requestTimeout: 18s
tcp:
connectTimeout: 15s
envoy-gateway/gateway-2:
@@ -331,10 +336,12 @@ xdsIR:
distinct: false
name: ""
prefix: /
+ timeout: 1s
traffic:
timeout:
http:
connectionIdleTimeout: 21s
maxConnectionDuration: 22s
+ requestTimeout: 23s
tcp:
connectTimeout: 20s
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.out.yaml
index efd290c9b1a..bb695decae7 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.out.yaml
@@ -210,7 +210,7 @@ xdsIR:
- h2
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
ciphers:
- cipher1
@@ -234,7 +234,7 @@ xdsIR:
- h2
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
ciphers:
- cipher1
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.in.yaml
new file mode 100644
index 00000000000..3b2331bba7f
--- /dev/null
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.in.yaml
@@ -0,0 +1,43 @@
+clientTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: target-gateway-1
+ spec:
+ headers:
+ enableEnvoyHeaders: true
+ withUnderscoresAction: Allow
+ preserveXRequestID: true
+ earlyRequestHeaders:
+ add:
+ - name: ""
+ value: "empty"
+ - name: "invalid"
+ value: ":/"
+ set:
+ - name: ""
+ value: "empty"
+ - name: "invalid"
+ value: ":/"
+ remove:
+ - ""
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http-1
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: Same
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.out.yaml
new file mode 100644
index 00000000000..9eee58d7df7
--- /dev/null
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.out.yaml
@@ -0,0 +1,127 @@
+clientTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: target-gateway-1
+ namespace: envoy-gateway
+ spec:
+ headers:
+ earlyRequestHeaders:
+ add:
+ - name: ""
+ value: empty
+ - name: invalid
+ value: :/
+ remove:
+ - ""
+ set:
+ - name: ""
+ value: empty
+ - name: invalid
+ value: :/
+ enableEnvoyHeaders: true
+ preserveXRequestID: true
+ withUnderscoresAction: Allow
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: |-
+ Headers: EarlyRequestHeaders cannot add a header with an empty name
+ EarlyRequestHeaders cannot set a header with an empty name
+ EarlyRequestHeaders cannot remove a header with an empty name.
+ reason: Invalid
+ status: "False"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http-1
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 0
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http-1
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http-1
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ headers:
+ enableEnvoyHeaders: true
+ preserveXRequestID: true
+ withUnderscoresAction: Allow
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-1
+ name: envoy-gateway/gateway-1/http-1
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml
index 6d73bee1a16..3234aed7da8 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml
@@ -9,6 +9,20 @@ clientTrafficPolicies:
enableEnvoyHeaders: true
withUnderscoresAction: Allow
preserveXRequestID: true
+ earlyRequestHeaders:
+ add:
+ - name: "my-added-header"
+ value: "my-added-header-value"
+ - name: "my-added-header"
+ value: "my-added-header-value"
+ set:
+ - name: "my-set-header"
+ value: "my-set-header-value"
+ - name: "my-set-header"
+ value: "my-set-header-value"
+ remove:
+ - "my-removed-header"
+ - "my-removed-header"
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml
index 8b32bb192da..4e66bd91c64 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml
@@ -7,6 +7,20 @@ clientTrafficPolicies:
namespace: envoy-gateway
spec:
headers:
+ earlyRequestHeaders:
+ add:
+ - name: my-added-header
+ value: my-added-header-value
+ - name: my-added-header
+ value: my-added-header-value
+ remove:
+ - my-removed-header
+ - my-removed-header
+ set:
+ - name: my-set-header
+ value: my-set-header-value
+ - name: my-set-header
+ value: my-set-header-value
enableEnvoyHeaders: true
preserveXRequestID: true
withUnderscoresAction: Allow
@@ -129,6 +143,17 @@ xdsIR:
http:
- address: 0.0.0.0
headers:
+ earlyAddRequestHeaders:
+ - append: true
+ name: my-added-header
+ value:
+ - my-added-header-value
+ - append: false
+ name: my-set-header
+ value:
+ - my-set-header-value
+ earlyRemoveRequestHeaders:
+ - my-removed-header
enableEnvoyHeaders: true
preserveXRequestID: true
withUnderscoresAction: Allow
@@ -147,6 +172,17 @@ xdsIR:
port: 10080
- address: 0.0.0.0
headers:
+ earlyAddRequestHeaders:
+ - append: true
+ name: my-added-header
+ value:
+ - my-added-header-value
+ - append: false
+ name: my-set-header
+ value:
+ - my-set-header-value
+ earlyRemoveRequestHeaders:
+ - my-removed-header
enableEnvoyHeaders: true
preserveXRequestID: true
withUnderscoresAction: Allow
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http-health-check.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http-health-check.out.yaml
old mode 100755
new mode 100644
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml
index 5ea01c15336..c4f16d4a2a1 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml
@@ -40,6 +40,34 @@ clientTrafficPolicies:
kind: Gateway
name: gateway-1
sectionName: http-3
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: target-gateway-1-section-http-4
+ spec:
+ http1:
+ http10:
+ useDefaultHost: true
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ sectionName: http-4
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: target-gateway-1-section-http-5
+ spec:
+ http1:
+ http10:
+ useDefaultHost: true
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ sectionName: http-5
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -68,3 +96,57 @@ gateways:
allowedRoutes:
namespaces:
from: Same
+ - name: http-4
+ protocol: HTTP
+ port: 8082
+ allowedRoutes:
+ namespaces:
+ from: Same
+ - name: http-5
+ protocol: HTTP
+ port: 8083
+ allowedRoutes:
+ namespaces:
+ from: Same
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: envoy-gateway
+ name: httproute-1
+ spec:
+ hostnames:
+ - route.example.com
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http-4
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http-5
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: envoy-gateway
+ name: httproute-2
+ spec:
+ hostnames:
+ - route2.example.com
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http-5
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml
index d0d0a8975e4..f7816b6f701 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml
@@ -89,6 +89,67 @@ clientTrafficPolicies:
status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: target-gateway-1-section-http-4
+ namespace: envoy-gateway
+ spec:
+ http1:
+ http10:
+ useDefaultHost: true
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ sectionName: http-4
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-4
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: target-gateway-1-section-http-5
+ namespace: envoy-gateway
+ spec:
+ http1:
+ http10:
+ useDefaultHost: true
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ sectionName: http-5
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-5
+ conditions:
+ - lastTransitionTime: null
+ message: 'HTTP1: cannot set http10 default host on listener with only wildcard
+ hostnames and more than one possible default route.'
+ reason: Invalid
+ status: "False"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -118,6 +179,18 @@ gateways:
name: http-3
port: 8081
protocol: HTTP
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http-4
+ port: 8082
+ protocol: HTTP
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http-5
+ port: 8083
+ protocol: HTTP
status:
listeners:
- attachedRoutes: 0
@@ -189,6 +262,148 @@ gateways:
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http-4
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http-5
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - route.example.com
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-4
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-5
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Service envoy-gateway/service-1 not found
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-4
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Service envoy-gateway/service-1 not found
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-5
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - route2.example.com
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-5
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Service envoy-gateway/service-1 not found
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-5
infraIR:
envoy-gateway/gateway-1:
proxy:
@@ -214,6 +429,20 @@ infraIR:
name: http-8081
protocol: HTTP
servicePort: 8081
+ - address: null
+ name: envoy-gateway/gateway-1/http-4
+ ports:
+ - containerPort: 8082
+ name: http-8082
+ protocol: HTTP
+ servicePort: 8082
+ - address: null
+ name: envoy-gateway/gateway-1/http-5
+ ports:
+ - containerPort: 8083
+ name: http-8083
+ protocol: HTTP
+ servicePort: 8083
metadata:
labels:
gateway.envoyproxy.io/owning-gateway-name: gateway-1
@@ -273,3 +502,76 @@ xdsIR:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 8081
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ http1:
+ http10:
+ defaultHost: route.example.com
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-4
+ name: envoy-gateway/gateway-1/http-4
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 8082
+ routes:
+ - directResponse:
+ statusCode: 500
+ hostname: route.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-1/rule/0/match/0/route_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ http1: {}
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-5
+ name: envoy-gateway/gateway-1/http-5
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 8083
+ routes:
+ - directResponse:
+ statusCode: 500
+ hostname: route.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-1/rule/0/match/0/route_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ - directResponse:
+ statusCode: 500
+ hostname: route2.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-2/rule/0/match/0/route2_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml
index cd1488caed4..c946f22c841 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml
@@ -169,9 +169,10 @@ xdsIR:
name: ""
prefix: /
tls:
+ alpnProtocols: null
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
maxVersion: "1.3"
minVersion: "1.2"
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml
index 3994993966c..22692261be3 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml
@@ -247,12 +247,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-1/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
@@ -291,12 +292,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-2/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-forward-client-cert-custom-data.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-forward-client-cert-custom-data.out.yaml
index 8d030ca0d23..285a35daf25 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-forward-client-cert-custom-data.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-forward-client-cert-custom-data.out.yaml
@@ -563,12 +563,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-1/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
@@ -615,12 +616,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-2/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
@@ -651,12 +653,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-3/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
@@ -689,12 +692,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-4/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
@@ -729,12 +733,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-5/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-forward-client-cert.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-forward-client-cert.out.yaml
index 57f75b69a32..85042934396 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-forward-client-cert.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-forward-client-cert.out.yaml
@@ -550,12 +550,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-1/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
@@ -602,12 +603,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-2/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
@@ -636,12 +638,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-3/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
@@ -670,12 +673,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-4/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
@@ -704,12 +708,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-5/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml
index 872ac5b5d17..08dcf5bef70 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml
@@ -246,12 +246,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-1/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
@@ -290,12 +291,13 @@ xdsIR:
mergeSlashes: true
port: 10443
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
name: envoy-gateway/target-gateway-2/ca.crt
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
maxVersion: "1.3"
minVersion: "1.2"
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.in.yaml
index 59dc2819c7c..ffe526627f2 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.in.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.in.yaml
@@ -22,6 +22,33 @@ clientTrafficPolicies:
signatureAlgorithms:
- sig1
- sig2
+ session:
+ resumption:
+ stateless: {}
+ stateful: {}
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: target-gateway-2
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ tls:
+ alpnProtocols: []
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: target-gateway-3
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-3
+ tls:
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -48,6 +75,44 @@ gateways:
allowedRoutes:
namespaces:
from: Same
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-2
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http-1
+ protocol: HTTPS
+ port: 443
+ allowedRoutes:
+ namespaces:
+ from: Same
+ tls:
+ mode: Terminate
+ certificateRefs:
+ - name: tls-secret-1
+ namespace: envoy-gateway
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-3
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http-1
+ protocol: HTTPS
+ port: 443
+ allowedRoutes:
+ namespaces:
+ from: Same
+ tls:
+ mode: Terminate
+ certificateRefs:
+ - name: tls-secret-1
+ namespace: envoy-gateway
secrets:
- apiVersion: v1
kind: Secret
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml
index f66ef90810d..e673ed66b7a 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml
@@ -20,6 +20,10 @@ clientTrafficPolicies:
- curve1
maxVersion: "1.3"
minVersion: "1.0"
+ session:
+ resumption:
+ stateful: {}
+ stateless: {}
signatureAlgorithms:
- sig1
- sig2
@@ -37,6 +41,57 @@ clientTrafficPolicies:
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: target-gateway-2
+ namespace: envoy-gateway
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ tls: {}
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: target-gateway-3
+ namespace: envoy-gateway
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-3
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-3
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -114,6 +169,100 @@ gateways:
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-2
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http-1
+ port: 443
+ protocol: HTTPS
+ tls:
+ certificateRefs:
+ - group: null
+ kind: null
+ name: tls-secret-1
+ namespace: envoy-gateway
+ mode: Terminate
+ status:
+ listeners:
+ - attachedRoutes: 0
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http-1
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-3
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http-1
+ port: 443
+ protocol: HTTPS
+ tls:
+ certificateRefs:
+ - group: null
+ kind: null
+ name: tls-secret-1
+ namespace: envoy-gateway
+ mode: Terminate
+ status:
+ listeners:
+ - attachedRoutes: 0
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http-1
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
infraIR:
envoy-gateway/gateway-1:
proxy:
@@ -137,6 +286,36 @@ infraIR:
gateway.envoyproxy.io/owning-gateway-name: gateway-1
gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
name: envoy-gateway/gateway-1
+ envoy-gateway/gateway-2:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-2/http-1
+ ports:
+ - containerPort: 10443
+ name: https-443
+ protocol: HTTPS
+ servicePort: 443
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-2
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-2
+ envoy-gateway/gateway-3:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-3/http-1
+ ports:
+ - containerPort: 10443
+ name: https-443
+ protocol: HTTPS
+ servicePort: 443
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-3
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-3
xdsIR:
envoy-gateway/gateway-1:
accessLog:
@@ -162,7 +341,7 @@ xdsIR:
- h2
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
ciphers:
- cipher1
@@ -174,6 +353,8 @@ xdsIR:
signatureAlgorithms:
- sig1
- sig2
+ statefulSessionResumption: true
+ statelessSessionResumption: true
- address: 0.0.0.0
hostnames:
- '*'
@@ -188,3 +369,57 @@ xdsIR:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 8080
+ envoy-gateway/gateway-2:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-2
+ namespace: envoy-gateway
+ sectionName: http-1
+ name: envoy-gateway/gateway-2/http-1
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10443
+ tls:
+ alpnProtocols: []
+ certificates:
+ - name: envoy-gateway/tls-secret-1
+ privateKey: '[redacted]'
+ serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
+ maxVersion: "1.3"
+ minVersion: "1.2"
+ envoy-gateway/gateway-3:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-3
+ namespace: envoy-gateway
+ sectionName: http-1
+ name: envoy-gateway/gateway-3/http-1
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10443
+ tls:
+ alpnProtocols: null
+ certificates:
+ - name: envoy-gateway/tls-secret-1
+ privateKey: '[redacted]'
+ serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
+ maxVersion: "1.3"
+ minVersion: "1.2"
diff --git a/internal/gatewayapi/testdata/custom-filter-order.in.yaml b/internal/gatewayapi/testdata/custom-filter-order.in.yaml
index 99b46e6de82..6f27637135c 100644
--- a/internal/gatewayapi/testdata/custom-filter-order.in.yaml
+++ b/internal/gatewayapi/testdata/custom-filter-order.in.yaml
@@ -111,7 +111,7 @@ envoyextensionpolicies:
type: HTTP
http:
url: https://www.example.com/wasm-filter-1.wasm
- sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
config:
parameter1:
key1: value1
@@ -122,7 +122,7 @@ envoyextensionpolicies:
type: HTTP
http:
url: https://www.example.com/wasm-filter-2.wasm
- sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980
+ sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e
config:
parameter1: value1
parameter2: value2
diff --git a/internal/gatewayapi/testdata/custom-filter-order.out.yaml b/internal/gatewayapi/testdata/custom-filter-order.out.yaml
index 6967bf280f3..9e2aa540081 100644
--- a/internal/gatewayapi/testdata/custom-filter-order.out.yaml
+++ b/internal/gatewayapi/testdata/custom-filter-order.out.yaml
@@ -13,7 +13,7 @@ envoyExtensionPolicies:
wasm:
- code:
http:
- sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
url: https://www.example.com/wasm-filter-1.wasm
type: HTTP
config:
@@ -24,7 +24,7 @@ envoyExtensionPolicies:
name: wasm-filter-1
- code:
http:
- sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980
+ sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e
url: https://www.example.com/wasm-filter-2.wasm
type: HTTP
config:
@@ -240,11 +240,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
envoyExtensions:
wasms:
@@ -257,7 +253,7 @@ xdsIR:
httpWasmCode:
originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm
servingURL: https://envoy-gateway:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm
- sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0
wasmName: wasm-filter-1
- config:
@@ -267,7 +263,7 @@ xdsIR:
httpWasmCode:
originalDownloadingURL: https://www.example.com/wasm-filter-2.wasm
servingURL: https://envoy-gateway:18002/593e4cc60a7e0fa4d4f86531a5e20e785213a52000f056a7a8b5c5afcb908052.wasm
- sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980
+ sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1
wasmName: wasm-filter-2
hostname: www.example.com
@@ -284,7 +280,7 @@ xdsIR:
security:
basicAuth:
name: securitypolicy/envoy-gateway/policy-for-gateway
- users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=
+ users: '[redacted]'
cors:
allowMethods:
- GET
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml
index 4f055e7bc4d..2c6b006af93 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml
@@ -296,7 +296,7 @@ xdsIR:
extProcs:
- authority: grpc-backend-2.default:8000
destination:
- name: envoyextensionpolicy/default/policy-for-route-1/0
+ name: envoyextensionpolicy/default/policy-for-route-1/extproc/0
settings:
- protocol: GRPC
weight: 1
@@ -325,7 +325,7 @@ xdsIR:
extProcs:
- authority: grpc-backend.envoy-gateway:9000
destination:
- name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0
+ name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0
settings:
- protocol: GRPC
weight: 1
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml
index f4cc57f95ba..51aa2de1c1b 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml
@@ -555,11 +555,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
envoyExtensions: {}
hostname: '*'
@@ -593,11 +589,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: grpcroute/envoy-gateway/grpcroute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
envoyExtensions: {}
headerMatches:
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml
index 6c7cfa25607..beac28da518 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml
@@ -154,6 +154,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: www.foo.com
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml
index c5c71bb503c..efd62e1e0ea 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml
@@ -154,6 +154,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: www.foo.com
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml
index a8a19dffa49..ba93c2decdc 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml
@@ -156,6 +156,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: www.foo.com
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml
index 4405c28c05d..066917dd152 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml
@@ -155,6 +155,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: www.foo.com
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml
index ca3297a5fae..a7c8128be50 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml
@@ -160,7 +160,7 @@ backendTLSPolicies:
- group: ''
kind: Service
name: grpc-backend
- sectionName: "8000"
+ sectionName: grpc
validation:
caCertificateRefs:
- name: ca-cmap
@@ -177,7 +177,7 @@ backendTLSPolicies:
- group: ''
kind: Service
name: grpc-backend-2
- sectionName: "9000"
+ sectionName: grpc
validation:
caCertificateRefs:
- name: ca-cmap
@@ -203,8 +203,13 @@ envoyExtensionPolicies:
processingMode:
request:
body: Buffered
+ attributes:
+ - request.path
response:
body: Streamed
+ attributes:
+ - xds.route_metadata
+ - connection.requested_server_name
messageTimeout: 5s
failOpen: true
- apiVersion: gateway.envoyproxy.io/v1alpha1
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml
index 4bfbd4e7df5..06461f085fe 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml
@@ -10,7 +10,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: grpc-backend
- sectionName: "8000"
+ sectionName: grpc
validation:
caCertificateRefs:
- group: ""
@@ -42,7 +42,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: grpc-backend-2
- sectionName: "9000"
+ sectionName: grpc
validation:
caCertificateRefs:
- group: ""
@@ -113,8 +113,13 @@ envoyExtensionPolicies:
messageTimeout: 5s
processingMode:
request:
+ attributes:
+ - request.path
body: Buffered
response:
+ attributes:
+ - xds.route_metadata
+ - connection.requested_server_name
body: Streamed
targetRef:
group: gateway.networking.k8s.io
@@ -308,7 +313,7 @@ xdsIR:
extProcs:
- authority: grpc-backend-2.default:9000
destination:
- name: envoyextensionpolicy/default/policy-for-http-route/0
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
settings:
- addressType: IP
endpoints:
@@ -316,6 +321,7 @@ xdsIR:
port: 9000
protocol: GRPC
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls-grpc-2/default-ca
@@ -348,11 +354,12 @@ xdsIR:
extProcs:
- authority: grpc-backend.envoy-gateway:8000
destination:
- name: envoyextensionpolicy/default/policy-for-gateway/0
+ name: envoyextensionpolicy/default/policy-for-gateway/extproc/0
settings:
- addressType: IP
protocol: GRPC
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls-grpc/envoy-gateway-ca
@@ -361,8 +368,13 @@ xdsIR:
failOpen: true
messageTimeout: 5s
name: envoyextensionpolicy/default/policy-for-gateway/extproc/0
+ requestAttributes:
+ - request.path
requestBodyProcessingMode: Buffered
requestHeaderProcessing: true
+ responseAttributes:
+ - xds.route_metadata
+ - connection.requested_server_name
responseBodyProcessingMode: Streamed
responseHeaderProcessing: true
hostname: www.bar.com
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml
index dad20362396..89be7cac752 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml
@@ -162,7 +162,7 @@ backendTLSPolicies:
- group: ''
kind: Service
name: grpc-backend
- sectionName: "8000"
+ sectionName: grpc
validation:
caCertificateRefs:
- name: ca-cmap
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml
index fda8a8185fc..5f1cd880246 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml
@@ -10,7 +10,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: grpc-backend
- sectionName: "8000"
+ sectionName: grpc
validation:
caCertificateRefs:
- group: ""
@@ -80,7 +80,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -98,7 +98,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
envoyExtensionPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyExtensionPolicy
@@ -308,11 +308,12 @@ xdsIR:
extProcs:
- authority: grpc-backend.envoy-gateway:8000
destination:
- name: envoyextensionpolicy/default/policy-for-http-route/0
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
settings:
- addressType: IP
protocol: GRPC
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls-grpc/envoy-gateway-ca
@@ -336,6 +337,7 @@ xdsIR:
port: 3443
protocol: GRPC
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls-backend-ip/envoy-gateway-ca
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml
new file mode 100644
index 00000000000..30af5a4dbd9
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml
@@ -0,0 +1,262 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /foo
+ backendRefs:
+ - name: service-1
+ port: 8080
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /bar
+ backendRefs:
+ - name: service-1
+ port: 8080
+services:
+- apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: envoy-gateway
+ name: grpc-backend
+ spec:
+ ports:
+ - port: 8000
+ name: grpc
+ protocol: TCP
+- apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: default
+ name: grpc-backend-2
+ spec:
+ ports:
+ - port: 9000
+ name: grpc
+ protocol: TCP
+endpointSlices:
+- apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-grpc-backend
+ namespace: envoy-gateway
+ labels:
+ kubernetes.io/service-name: grpc-backend
+ addressType: IPv4
+ ports:
+ - name: http
+ protocol: TCP
+ port: 8000
+ endpoints:
+ - addresses:
+ - 7.7.7.7
+ conditions:
+ ready: true
+- apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-grpc-backend-2
+ namespace: default
+ labels:
+ kubernetes.io/service-name: grpc-backend-2
+ addressType: IPv4
+ ports:
+ - name: grpc
+ protocol: TCP
+ port: 9000
+ endpoints:
+ - addresses:
+ - 8.8.8.8
+ conditions:
+ ready: true
+referenceGrants:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: ReferenceGrant
+ metadata:
+ namespace: envoy-gateway
+ name: referencegrant-1
+ spec:
+ from:
+ - group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ namespace: default
+ to:
+ - group: ''
+ kind: Service
+ - group: gateway.envoyproxy.io
+ kind: Backend
+configMaps:
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: ca-cmap
+ namespace: default
+ data:
+ ca.crt: |
+ -----BEGIN CERTIFICATE-----
+ MIIDJzCCAg+gAwIBAgIUAl6UKIuKmzte81cllz5PfdN2IlIwDQYJKoZIhvcNAQEL
+ BQAwIzEQMA4GA1UEAwwHbXljaWVudDEPMA0GA1UECgwGa3ViZWRiMB4XDTIzMTAw
+ MjA1NDE1N1oXDTI0MTAwMTA1NDE1N1owIzEQMA4GA1UEAwwHbXljaWVudDEPMA0G
+ A1UECgwGa3ViZWRiMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSTc
+ 1yj8HW62nynkFbXo4VXKv2jC0PM7dPVky87FweZcTKLoWQVPQE2p2kLDK6OEszmM
+ yyr+xxWtyiveremrWqnKkNTYhLfYPhgQkczib7eUalmFjUbhWdLvHakbEgCodn3b
+ kz57mInX2VpiDOKg4kyHfiuXWpiBqrCx0KNLpxo3DEQcFcsQTeTHzh4752GV04RU
+ Ti/GEWyzIsl4Rg7tGtAwmcIPgUNUfY2Q390FGqdH4ahn+mw/6aFbW31W63d9YJVq
+ ioyOVcaMIpM5B/c7Qc8SuhCI1YGhUyg4cRHLEw5VtikioyE3X04kna3jQAj54YbR
+ bpEhc35apKLB21HOUQIDAQABo1MwUTAdBgNVHQ4EFgQUyvl0VI5vJVSuYFXu7B48
+ 6PbMEAowHwYDVR0jBBgwFoAUyvl0VI5vJVSuYFXu7B486PbMEAowDwYDVR0TAQH/
+ BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAMLxrgFVMuNRq2wAwcBt7SnNR5Cfz
+ 2MvXq5EUmuawIUi9kaYjwdViDREGSjk7JW17vl576HjDkdfRwi4E28SydRInZf6J
+ i8HZcZ7caH6DxR335fgHVzLi5NiTce/OjNBQzQ2MJXVDd8DBmG5fyatJiOJQ4bWE
+ A7FlP0RdP3CO3GWE0M5iXOB2m1qWkE2eyO4UHvwTqNQLdrdAXgDQlbam9e4BG3Gg
+ d/6thAkWDbt/QNT+EJHDCvhDRKh1RuGHyg+Y+/nebTWWrFWsktRrbOoHCZiCpXI1
+ 3eXE6nt0YkgtDxG22KqnhpAg9gUSs2hlhoxyvkzyF0mu6NhPlwAgnq7+/Q==
+ -----END CERTIFICATE-----
+backendTLSPolicies:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-grpc
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: ''
+ kind: Service
+ name: grpc-backend
+ sectionName: grpc
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: grpc-backend
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-backend-ip
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: ip-backend
+envoyExtensionPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ extProc:
+ - backendRefs:
+ - Name: grpc-backend
+ Namespace: envoy-gateway
+ Port: 8000
+ - Name: grpc-backend-2
+ Port: 9000
+ - Name: backend-ip
+ Kind: Backend
+ Group: gateway.envoyproxy.io
+ - Name: backend-ip-tls
+ Namespace: envoy-gateway
+ Kind: Backend
+ Group: gateway.envoyproxy.io
+ backendSettings:
+ dns:
+ respectDnsTtl: true
+ http2:
+ initialStreamWindowSize: 128Ki
+ initialConnectionWindowSize: 2Mi
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ type: ConsistentHash
+ consistentHash:
+ type: Header
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ circuitBreaker:
+ maxConnections: 2048
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ connection:
+ bufferLimit: 20Mi
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml
new file mode 100644
index 00000000000..df04fea804f
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml
@@ -0,0 +1,433 @@
+backendTLSPolicies:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-grpc
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: ""
+ kind: Service
+ name: grpc-backend
+ sectionName: grpc
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: grpc-backend
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ name: policy-for-http-route
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-backend-ip
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: ip-backend
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ name: policy-for-http-route
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+envoyExtensionPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route
+ namespace: default
+ spec:
+ extProc:
+ - backendRefs:
+ - name: grpc-backend
+ namespace: envoy-gateway
+ port: 8000
+ - name: grpc-backend-2
+ port: 9000
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ backendSettings:
+ circuitBreaker:
+ maxConnections: 2048
+ connection:
+ bufferLimit: 20Mi
+ dns:
+ respectDnsTtl: true
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 2Mi
+ initialStreamWindowSize: 128Ki
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ type: Header
+ type: ConsistentHash
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /bar
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+infraIR:
+ default/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-1
+xdsIR:
+ default/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ envoyExtensions:
+ extProcs:
+ - authority: grpc-backend.envoy-gateway:8000
+ destination:
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ settings:
+ - addressType: IP
+ protocol: GRPC
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-grpc/envoy-gateway-ca
+ sni: grpc-backend
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 9000
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3443
+ protocol: GRPC
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sni: ip-backend
+ weight: 1
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ dns:
+ respectDnsTtl: true
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 131072
+ initialStreamWindowSize: 2097152
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.in.yaml
new file mode 100644
index 00000000000..c4184d15476
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.in.yaml
@@ -0,0 +1,123 @@
+secrets:
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ namespace: envoy-gateway
+ name: my-pull-secret
+ data:
+ .dockerconfigjson: VGhpc0lzTm90QVJlYWxEb2NrZXJDb25maWdKc29u
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.example.com
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/foo"
+ backendRefs:
+ - name: service-1
+ port: 8080
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - www.example.com
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/bar"
+ backendRefs:
+ - name: service-1
+ port: 8080
+envoyextensionpolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: policy-for-gateway # This policy should attach httproute-2
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ wasm:
+ - name: wasm-filter-1
+ code:
+ type: HTTP
+ http:
+ url: https://www.example.com/wasm-filter-1.wasm
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
+ env:
+ hostKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
+ - name: wasm-filter-2
+ rootID: "my-root-id"
+ code:
+ type: Image
+ image:
+ url: oci://www.example.com/wasm-filter-2:v1.0.0
+ pullSecretRef:
+ name: my-pull-secret
+ sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46
+ env:
+ hostKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
+ - code:
+ type: Image
+ image:
+ url: www.example.com:8080/wasm-filter-3
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route # This policy should attach httproute-1
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ wasm:
+ - name: wasm-filter-4
+ code:
+ type: HTTP
+ http:
+ url: https://www.test.com/wasm-filter-4.wasm
+ sha256: b6922722ab58109abfaa8d9eb16f339b38b2bb1c17076b083b34438b934e7463
+ failOpen: true
+ env:
+ hostKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml
new file mode 100644
index 00000000000..4a19852eea0
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml
@@ -0,0 +1,342 @@
+envoyExtensionPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route
+ namespace: default
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ wasm:
+ - code:
+ http:
+ sha256: b6922722ab58109abfaa8d9eb16f339b38b2bb1c17076b083b34438b934e7463
+ url: https://www.test.com/wasm-filter-4.wasm
+ type: HTTP
+ env:
+ hostKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
+ failOpen: true
+ name: wasm-filter-4
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-gateway
+ namespace: envoy-gateway
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ wasm:
+ - code:
+ http:
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
+ url: https://www.example.com/wasm-filter-1.wasm
+ type: HTTP
+ env:
+ hostKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
+ name: wasm-filter-1
+ - code:
+ image:
+ pullSecretRef:
+ group: null
+ kind: null
+ name: my-pull-secret
+ sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46
+ url: oci://www.example.com/wasm-filter-2:v1.0.0
+ type: Image
+ env:
+ hostKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
+ name: wasm-filter-2
+ rootID: my-root-id
+ - code:
+ image:
+ sha256: null
+ url: www.example.com:8080/wasm-filter-3
+ type: Image
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: 'This policy is being overridden by other envoyExtensionPolicies
+ for these routes: [default/httproute-1]'
+ reason: Overridden
+ status: "True"
+ type: Overridden
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.example.com
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - www.example.com
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /bar
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ envoyExtensions:
+ wasms:
+ - config: null
+ failOpen: true
+ hostKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
+ httpWasmCode:
+ originalDownloadingURL: https://www.test.com/wasm-filter-4.wasm
+ servingURL: https://envoy-gateway:18002/fe571e7b1ef5dc626ceb2c2c86782a134a92989a2643485238951696ae4334c3.wasm
+ sha256: b6922722ab58109abfaa8d9eb16f339b38b2bb1c17076b083b34438b934e7463
+ name: envoyextensionpolicy/default/policy-for-http-route/wasm/0
+ wasmName: wasm-filter-4
+ hostname: www.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ envoyExtensions:
+ wasms:
+ - config: null
+ failOpen: false
+ hostKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
+ httpWasmCode:
+ originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm
+ servingURL: https://envoy-gateway:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
+ name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0
+ wasmName: wasm-filter-1
+ - config: null
+ failOpen: false
+ hostKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
+ httpWasmCode:
+ originalDownloadingURL: oci://www.example.com/wasm-filter-2:v1.0.0
+ servingURL: https://envoy-gateway:18002/7abf116e5cd5a20389604a5ba0f3bd04fdf76f92181fe67506b42c2ee596d3fd.wasm
+ sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46
+ name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1
+ rootID: my-root-id
+ wasmName: wasm-filter-2
+ - config: null
+ failOpen: false
+ httpWasmCode:
+ originalDownloadingURL: oci://www.example.com:8080/wasm-filter-3:latest
+ servingURL: https://envoy-gateway:18002/42d30b4a4cc631415e6e48c02d244700da327201eb273f752cacf745715b31d9.wasm
+ sha256: 2a19e4f337e5223d7287e7fccd933fb01905deaff804292e5257f8c681b82bee
+ name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2
+ wasmName: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2
+ hostname: www.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.in.yaml
index 106267da645..17026ebbad6 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.in.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.in.yaml
@@ -72,7 +72,7 @@ envoyextensionpolicies:
type: HTTP
http:
url: https://www.example.com/wasm-filter-1.wasm
- sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
config:
parameter1:
key1: value1
@@ -83,7 +83,7 @@ envoyextensionpolicies:
type: HTTP
http:
url: https://www.example.com/wasm-filter-2.wasm
- sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980
+ sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e
config:
parameter1: value1
parameter2: value2
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml
index 4abc9f59092..f61cabdcffa 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml
@@ -16,7 +16,7 @@ envoyExtensionPolicies:
wasm:
- code:
http:
- sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
url: https://www.example.com/wasm-filter-1.wasm
type: HTTP
config:
@@ -27,7 +27,7 @@ envoyExtensionPolicies:
name: wasm-filter-1
- code:
http:
- sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980
+ sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e
url: https://www.example.com/wasm-filter-2.wasm
type: HTTP
config:
@@ -222,11 +222,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
envoyExtensions:
wasms:
@@ -239,7 +235,7 @@ xdsIR:
httpWasmCode:
originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm
servingURL: https://envoy-gateway:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm
- sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0
wasmName: wasm-filter-1
- config:
@@ -249,7 +245,7 @@ xdsIR:
httpWasmCode:
originalDownloadingURL: https://www.example.com/wasm-filter-2.wasm
servingURL: https://envoy-gateway:18002/593e4cc60a7e0fa4d4f86531a5e20e785213a52000f056a7a8b5c5afcb908052.wasm
- sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980
+ sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1
wasmName: wasm-filter-2
hostname: www.example.com
@@ -263,11 +259,7 @@ xdsIR:
distinct: false
name: ""
prefix: /foo
- - destination:
- name: httproute/envoy-gateway/httproute-2/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
envoyExtensions:
wasms:
@@ -280,7 +272,7 @@ xdsIR:
httpWasmCode:
originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm
servingURL: https://envoy-gateway:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm
- sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0
wasmName: wasm-filter-1
- config:
@@ -290,7 +282,7 @@ xdsIR:
httpWasmCode:
originalDownloadingURL: https://www.example.com/wasm-filter-2.wasm
servingURL: https://envoy-gateway:18002/593e4cc60a7e0fa4d4f86531a5e20e785213a52000f056a7a8b5c5afcb908052.wasm
- sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980
+ sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1
wasmName: wasm-filter-2
hostname: www.example.com
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml
index 5cb2b192553..e7414013410 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml
@@ -77,7 +77,7 @@ envoyextensionpolicies:
type: HTTP
http:
url: https://www.example.com/wasm-filter-1.wasm
- sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
config:
parameter1:
key1: value1
@@ -91,7 +91,7 @@ envoyextensionpolicies:
url: oci://www.example.com/wasm-filter-2:v1.0.0
pullSecretRef:
name: my-pull-secret
- sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980
+ sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46
config:
parameter1: value1
parameter2: value2
@@ -115,7 +115,7 @@ envoyextensionpolicies:
type: HTTP
http:
url: https://www.test.com/wasm-filter-4.wasm
- sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6
+ sha256: b6922722ab58109abfaa8d9eb16f339b38b2bb1c17076b083b34438b934e7463
config:
parameter1:
key1: value1
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml
index 68cfaf92515..368c32a4055 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml
@@ -13,7 +13,7 @@ envoyExtensionPolicies:
wasm:
- code:
http:
- sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6
+ sha256: b6922722ab58109abfaa8d9eb16f339b38b2bb1c17076b083b34438b934e7463
url: https://www.test.com/wasm-filter-4.wasm
type: HTTP
config:
@@ -53,7 +53,7 @@ envoyExtensionPolicies:
wasm:
- code:
http:
- sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
url: https://www.example.com/wasm-filter-1.wasm
type: HTTP
config:
@@ -68,7 +68,7 @@ envoyExtensionPolicies:
group: null
kind: null
name: my-pull-secret
- sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980
+ sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46
url: oci://www.example.com/wasm-filter-2:v1.0.0
type: Image
config:
@@ -277,7 +277,7 @@ xdsIR:
httpWasmCode:
originalDownloadingURL: https://www.test.com/wasm-filter-4.wasm
servingURL: https://envoy-gateway:18002/fe571e7b1ef5dc626ceb2c2c86782a134a92989a2643485238951696ae4334c3.wasm
- sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6
+ sha256: b6922722ab58109abfaa8d9eb16f339b38b2bb1c17076b083b34438b934e7463
name: envoyextensionpolicy/default/policy-for-http-route/wasm/0
wasmName: wasm-filter-4
hostname: www.example.com
@@ -311,7 +311,7 @@ xdsIR:
httpWasmCode:
originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm
servingURL: https://envoy-gateway:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm
- sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5
+ sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0
wasmName: wasm-filter-1
- config:
diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-als-json.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-als-json.out.yaml
old mode 100755
new mode 100644
diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-types.in.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-types.in.yaml
new file mode 100644
index 00000000000..03977e33075
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-types.in.yaml
@@ -0,0 +1,236 @@
+envoyProxyForGatewayClass:
+ apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyProxy
+ metadata:
+ namespace: envoy-gateway-system
+ name: test
+ spec:
+ telemetry:
+ accessLog:
+ settings:
+ - type: Route
+ - type: Listener
+ - type: Route
+ format:
+ type: Text
+ text: |
+ this is a route log
+ sinks:
+ - type: File
+ file:
+ path: /dev/stdout
+ - type: ALS
+ als:
+ logName: accesslog
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ type: HTTP
+ - type: ALS
+ als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ type: TCP
+ - type: OpenTelemetry
+ openTelemetry:
+ host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ resources:
+ k8s.cluster.name: "cluster-1"
+ - type: Listener
+ format:
+ type: Text
+ text: |
+ this is a listener log
+ sinks:
+ - type: File
+ file:
+ path: /dev/stdout
+ - type: ALS
+ als:
+ logName: accesslog
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ type: HTTP
+ - type: ALS
+ als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ type: TCP
+ - type: OpenTelemetry
+ openTelemetry:
+ host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ resources:
+ k8s.cluster.name: "cluster-1"
+ - format:
+ type: Text
+ text: |
+ this is a Global log
+ sinks:
+ - type: File
+ file:
+ path: /dev/stdout
+ - type: ALS
+ als:
+ logName: accesslog
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ type: HTTP
+ - type: ALS
+ als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ type: TCP
+ - type: OpenTelemetry
+ openTelemetry:
+ host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ resources:
+ k8s.cluster.name: "cluster-1"
+ provider:
+ type: Kubernetes
+ kubernetes:
+ envoyService:
+ type: LoadBalancer
+ envoyDeployment:
+ replicas: 2
+ container:
+ env:
+ - name: env_a
+ value: env_a_value
+ - name: env_b
+ value: env_b_name
+ image: "envoyproxy/envoy:distroless-dev"
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ runAsUser: 2000
+ allowPrivilegeEscalation: false
+ pod:
+ annotations:
+ key1: val1
+ key2: val2
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: cloud.google.com/gke-nodepool
+ operator: In
+ values:
+ - router-node
+ tolerations:
+ - effect: NoSchedule
+ key: node-type
+ operator: Exists
+ value: "router"
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 3000
+ fsGroup: 2000
+ fsGroupChangePolicy: "OnRootMismatch"
+ volumes:
+ - name: certs
+ secret:
+ secretName: envoy-cert
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: Same
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: envoy-gateway
+ name: httproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ rules:
+ - matches:
+ - path:
+ type: Exact
+ value: "/exact"
+ backendRefs:
+ - name: service-1
+ port: 8080
+services:
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: envoy-als
+ namespace: monitoring
+ spec:
+ type: ClusterIP
+ ports:
+ - name: grpc
+ port: 9000
+ appProtocol: grpc
+ protocol: TCP
+ targetPort: 9000
+endpointSlices:
+- apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-envoy-als
+ namespace: monitoring
+ labels:
+ kubernetes.io/service-name: envoy-als
+ addressType: IPv4
+ ports:
+ - name: grpc
+ protocol: TCP
+ appProtocol: grpc
+ port: 9090
+ endpoints:
+ - addresses:
+ - "10.240.0.10"
+ conditions:
+ ready: true
diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-types.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-types.out.yaml
new file mode 100644
index 00000000000..ee6c126ab9b
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-types.out.yaml
@@ -0,0 +1,456 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ type: Exact
+ value: /exact
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Service envoy-gateway/service-1 not found
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ config:
+ apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyProxy
+ metadata:
+ creationTimestamp: null
+ name: test
+ namespace: envoy-gateway-system
+ spec:
+ logging: {}
+ provider:
+ kubernetes:
+ envoyDeployment:
+ container:
+ env:
+ - name: env_a
+ value: env_a_value
+ - name: env_b
+ value: env_b_name
+ image: envoyproxy/envoy:distroless-dev
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ runAsUser: 2000
+ pod:
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: cloud.google.com/gke-nodepool
+ operator: In
+ values:
+ - router-node
+ annotations:
+ key1: val1
+ key2: val2
+ securityContext:
+ fsGroup: 2000
+ fsGroupChangePolicy: OnRootMismatch
+ runAsGroup: 3000
+ runAsUser: 1000
+ tolerations:
+ - effect: NoSchedule
+ key: node-type
+ operator: Exists
+ value: router
+ volumes:
+ - name: certs
+ secret:
+ secretName: envoy-cert
+ replicas: 2
+ envoyService:
+ type: LoadBalancer
+ type: Kubernetes
+ telemetry:
+ accessLog:
+ settings:
+ - sinks: null
+ type: Route
+ - sinks: null
+ type: Listener
+ - format:
+ text: |
+ this is a route log
+ type: Text
+ sinks:
+ - file:
+ path: /dev/stdout
+ type: File
+ - als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ logName: accesslog
+ type: HTTP
+ type: ALS
+ - als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ type: TCP
+ type: ALS
+ - openTelemetry:
+ host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ resources:
+ k8s.cluster.name: cluster-1
+ type: OpenTelemetry
+ type: Route
+ - format:
+ text: |
+ this is a listener log
+ type: Text
+ sinks:
+ - file:
+ path: /dev/stdout
+ type: File
+ - als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ logName: accesslog
+ type: HTTP
+ type: ALS
+ - als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ type: TCP
+ type: ALS
+ - openTelemetry:
+ host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ resources:
+ k8s.cluster.name: cluster-1
+ type: OpenTelemetry
+ type: Listener
+ - format:
+ text: |
+ this is a Global log
+ type: Text
+ sinks:
+ - file:
+ path: /dev/stdout
+ type: File
+ - als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ logName: accesslog
+ type: HTTP
+ type: ALS
+ - als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ type: TCP
+ type: ALS
+ - openTelemetry:
+ host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ resources:
+ k8s.cluster.name: cluster-1
+ type: OpenTelemetry
+ status: {}
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ als:
+ - destination:
+ name: accesslog_als_2_1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ logType: Route
+ name: accesslog
+ text: |
+ this is a route log
+ type: HTTP
+ - destination:
+ name: accesslog_als_2_2
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ logType: Route
+ name: envoy-gateway-system/test
+ text: |
+ this is a route log
+ type: TCP
+ - destination:
+ name: accesslog_als_3_1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ logType: Listener
+ name: accesslog
+ text: |
+ this is a listener log
+ type: HTTP
+ - destination:
+ name: accesslog_als_3_2
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ logType: Listener
+ name: envoy-gateway-system/test
+ text: |
+ this is a listener log
+ type: TCP
+ - destination:
+ name: accesslog_als_4_1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ name: accesslog
+ text: |
+ this is a Global log
+ type: HTTP
+ - destination:
+ name: accesslog_als_4_2
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ name: envoy-gateway-system/test
+ text: |
+ this is a Global log
+ type: TCP
+ openTelemetry:
+ - authority: otel-collector.monitoring.svc.cluster.local
+ destination:
+ name: accesslog_otel_2_3
+ settings:
+ - endpoints:
+ - host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ protocol: GRPC
+ weight: 1
+ logType: Route
+ resources:
+ k8s.cluster.name: cluster-1
+ text: |
+ this is a route log
+ - authority: otel-collector.monitoring.svc.cluster.local
+ destination:
+ name: accesslog_otel_3_3
+ settings:
+ - endpoints:
+ - host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ protocol: GRPC
+ weight: 1
+ logType: Listener
+ resources:
+ k8s.cluster.name: cluster-1
+ text: |
+ this is a listener log
+ - authority: otel-collector.monitoring.svc.cluster.local
+ destination:
+ name: accesslog_otel_4_3
+ settings:
+ - endpoints:
+ - host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ protocol: GRPC
+ weight: 1
+ resources:
+ k8s.cluster.name: cluster-1
+ text: |
+ this is a Global log
+ text:
+ - logType: Route
+ path: /dev/stdout
+ - logType: Listener
+ path: /dev/stdout
+ - format: |
+ this is a route log
+ logType: Route
+ path: /dev/stdout
+ - format: |
+ this is a listener log
+ logType: Listener
+ path: /dev/stdout
+ - format: |
+ this is a Global log
+ path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ exact: /exact
+ name: ""
diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.in.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.in.yaml
new file mode 100644
index 00000000000..72d40451a1f
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.in.yaml
@@ -0,0 +1,196 @@
+envoyProxyForGatewayClass:
+ apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyProxy
+ metadata:
+ namespace: envoy-gateway-system
+ name: test
+ spec:
+ telemetry:
+ accessLog:
+ settings:
+ - format:
+ type: Text
+ text: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ sinks:
+ - type: File
+ file:
+ path: /dev/stdout
+ - type: ALS
+ als:
+ logName: accesslog
+ backendSettings:
+ http2:
+ initialStreamWindowSize: 128Ki
+ initialConnectionWindowSize: 2Mi
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ type: ConsistentHash
+ consistentHash:
+ type: Header
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ circuitBreaker:
+ maxConnections: 2048
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ connection:
+ bufferLimit: 20Mi
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ type: HTTP
+ - type: ALS
+ als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ type: TCP
+ - type: OpenTelemetry
+ openTelemetry:
+ backendSettings:
+ http2:
+ initialStreamWindowSize: 128Ki
+ initialConnectionWindowSize: 2Mi
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ type: ConsistentHash
+ consistentHash:
+ type: Header
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ circuitBreaker:
+ maxConnections: 2048
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ connection:
+ bufferLimit: 20Mi
+ host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ resources:
+ k8s.cluster.name: "cluster-1"
+ provider:
+ type: Kubernetes
+ kubernetes:
+ envoyService:
+ type: LoadBalancer
+ envoyDeployment:
+ replicas: 2
+ container:
+ env:
+ - name: env_a
+ value: env_a_value
+ - name: env_b
+ value: env_b_name
+ image: "envoyproxy/envoy:distroless-dev"
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ runAsUser: 2000
+ allowPrivilegeEscalation: false
+ pod:
+ annotations:
+ key1: val1
+ key2: val2
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: cloud.google.com/gke-nodepool
+ operator: In
+ values:
+ - router-node
+ tolerations:
+ - effect: NoSchedule
+ key: node-type
+ operator: Exists
+ value: "router"
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 3000
+ fsGroup: 2000
+ fsGroupChangePolicy: "OnRootMismatch"
+ volumes:
+ - name: certs
+ secret:
+ secretName: envoy-cert
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: Same
+services:
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: envoy-als
+ namespace: monitoring
+ spec:
+ type: ClusterIP
+ ports:
+ - name: grpc
+ port: 9000
+ appProtocol: grpc
+ protocol: TCP
+ targetPort: 9000
+endpointSlices:
+- apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-envoy-als
+ namespace: monitoring
+ labels:
+ kubernetes.io/service-name: envoy-als
+ addressType: IPv4
+ ports:
+ - name: grpc
+ protocol: TCP
+ appProtocol: grpc
+ port: 9090
+ endpoints:
+ - addresses:
+ - "10.240.0.10"
+ conditions:
+ ready: true
diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml
new file mode 100644
index 00000000000..28ef831b03a
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml
@@ -0,0 +1,326 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 0
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ config:
+ apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyProxy
+ metadata:
+ creationTimestamp: null
+ name: test
+ namespace: envoy-gateway-system
+ spec:
+ logging: {}
+ provider:
+ kubernetes:
+ envoyDeployment:
+ container:
+ env:
+ - name: env_a
+ value: env_a_value
+ - name: env_b
+ value: env_b_name
+ image: envoyproxy/envoy:distroless-dev
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ runAsUser: 2000
+ pod:
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: cloud.google.com/gke-nodepool
+ operator: In
+ values:
+ - router-node
+ annotations:
+ key1: val1
+ key2: val2
+ securityContext:
+ fsGroup: 2000
+ fsGroupChangePolicy: OnRootMismatch
+ runAsGroup: 3000
+ runAsUser: 1000
+ tolerations:
+ - effect: NoSchedule
+ key: node-type
+ operator: Exists
+ value: router
+ volumes:
+ - name: certs
+ secret:
+ secretName: envoy-cert
+ replicas: 2
+ envoyService:
+ type: LoadBalancer
+ type: Kubernetes
+ telemetry:
+ accessLog:
+ settings:
+ - format:
+ text: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ type: Text
+ sinks:
+ - file:
+ path: /dev/stdout
+ type: File
+ - als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ backendSettings:
+ circuitBreaker:
+ maxConnections: 2048
+ connection:
+ bufferLimit: 20Mi
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 2Mi
+ initialStreamWindowSize: 128Ki
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ type: Header
+ type: ConsistentHash
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ logName: accesslog
+ type: HTTP
+ type: ALS
+ - als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ type: TCP
+ type: ALS
+ - openTelemetry:
+ backendSettings:
+ circuitBreaker:
+ maxConnections: 2048
+ connection:
+ bufferLimit: 20Mi
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 2Mi
+ initialStreamWindowSize: 128Ki
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ type: Header
+ type: ConsistentHash
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ resources:
+ k8s.cluster.name: cluster-1
+ type: OpenTelemetry
+ status: {}
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ als:
+ - destination:
+ name: accesslog_als_0_1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ name: accesslog
+ text: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 131072
+ initialStreamWindowSize: 2097152
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ type: HTTP
+ - destination:
+ name: accesslog_als_0_2
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ name: envoy-gateway-system/test
+ text: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ type: TCP
+ openTelemetry:
+ - authority: otel-collector.monitoring.svc.cluster.local
+ destination:
+ name: accesslog_otel_0_3
+ settings:
+ - endpoints:
+ - host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ protocol: GRPC
+ weight: 1
+ resources:
+ k8s.cluster.name: cluster-1
+ text: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 131072
+ initialStreamWindowSize: 2097152
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ text:
+ - format: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
diff --git a/internal/gatewayapi/testdata/envoyproxy-endpoint-routing-for-gateway.out.yaml b/internal/gatewayapi/testdata/envoyproxy-endpoint-routing-for-gateway.out.yaml
old mode 100755
new mode 100644
diff --git a/internal/gatewayapi/testdata/envoyproxy-endpoint-routing.out.yaml b/internal/gatewayapi/testdata/envoyproxy-endpoint-routing.out.yaml
old mode 100755
new mode 100644
diff --git a/internal/gatewayapi/testdata/envoyproxy-metric-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-metric-backend.out.yaml
index 262d55065a9..4bff8f998d5 100644
--- a/internal/gatewayapi/testdata/envoyproxy-metric-backend.out.yaml
+++ b/internal/gatewayapi/testdata/envoyproxy-metric-backend.out.yaml
@@ -144,4 +144,5 @@ xdsIR:
port: 10080
metrics:
enablePerEndpointStats: false
+ enableRequestResponseSizesStats: false
enableVirtualHostStats: false
diff --git a/internal/gatewayapi/testdata/envoyproxy-metric-enabled-backend.in.yaml b/internal/gatewayapi/testdata/envoyproxy-metric-enabled-backend.in.yaml
new file mode 100644
index 00000000000..e958af1e119
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-metric-enabled-backend.in.yaml
@@ -0,0 +1,82 @@
+envoyProxyForGatewayClass:
+ apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyProxy
+ metadata:
+ namespace: envoy-gateway-system
+ name: test
+ spec:
+ telemetry:
+ metrics:
+ sinks:
+ - type: OpenTelemetry
+ openTelemetry:
+ backendRefs:
+ - name: otel-collector
+ namespace: monitoring
+ port: 4317
+ enableVirtualHostStats: true
+ enablePerEndpointStats: true
+ enableRequestResponseSizesStats: true
+ provider:
+ type: Kubernetes
+ kubernetes:
+ envoyService:
+ type: LoadBalancer
+ envoyDeployment:
+ replicas: 2
+ container:
+ env:
+ - name: env_a
+ value: env_a_value
+ - name: env_b
+ value: env_b_name
+ image: "envoyproxy/envoy:distroless-dev"
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ runAsUser: 2000
+ allowPrivilegeEscalation: false
+ pod:
+ annotations:
+ key1: val1
+ key2: val2
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: cloud.google.com/gke-nodepool
+ operator: In
+ values:
+ - router-node
+ tolerations:
+ - effect: NoSchedule
+ key: node-type
+ operator: Exists
+ value: "router"
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 3000
+ fsGroup: 2000
+ fsGroupChangePolicy: "OnRootMismatch"
+ volumes:
+ - name: certs
+ secret:
+ secretName: envoy-cert
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: Same
diff --git a/internal/gatewayapi/testdata/envoyproxy-metric-enabled-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-metric-enabled-backend.out.yaml
new file mode 100644
index 00000000000..7605114bf22
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-metric-enabled-backend.out.yaml
@@ -0,0 +1,151 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 0
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ config:
+ apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyProxy
+ metadata:
+ creationTimestamp: null
+ name: test
+ namespace: envoy-gateway-system
+ spec:
+ logging: {}
+ provider:
+ kubernetes:
+ envoyDeployment:
+ container:
+ env:
+ - name: env_a
+ value: env_a_value
+ - name: env_b
+ value: env_b_name
+ image: envoyproxy/envoy:distroless-dev
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ runAsUser: 2000
+ pod:
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: cloud.google.com/gke-nodepool
+ operator: In
+ values:
+ - router-node
+ annotations:
+ key1: val1
+ key2: val2
+ securityContext:
+ fsGroup: 2000
+ fsGroupChangePolicy: OnRootMismatch
+ runAsGroup: 3000
+ runAsUser: 1000
+ tolerations:
+ - effect: NoSchedule
+ key: node-type
+ operator: Exists
+ value: router
+ volumes:
+ - name: certs
+ secret:
+ secretName: envoy-cert
+ replicas: 2
+ envoyService:
+ type: LoadBalancer
+ type: Kubernetes
+ telemetry:
+ metrics:
+ enablePerEndpointStats: true
+ enableRequestResponseSizesStats: true
+ enableVirtualHostStats: true
+ sinks:
+ - openTelemetry:
+ backendRefs:
+ - name: otel-collector
+ namespace: monitoring
+ port: 4317
+ type: OpenTelemetry
+ status: {}
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ metrics:
+ enablePerEndpointStats: true
+ enableRequestResponseSizesStats: true
+ enableVirtualHostStats: true
diff --git a/internal/gatewayapi/testdata/envoyproxy-priority-backend.in.yaml b/internal/gatewayapi/testdata/envoyproxy-priority-backend.in.yaml
new file mode 100644
index 00000000000..42e46b8990e
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-priority-backend.in.yaml
@@ -0,0 +1,236 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /foo
+ backendRefs:
+ - name: service-1
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /bar
+ backendRefs:
+ - name: service-1
+ port: 8080
+services:
+ - apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: envoy-gateway
+ name: grpc-backend
+ spec:
+ ports:
+ - port: 8000
+ name: grpc
+ protocol: TCP
+ - apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: default
+ name: grpc-backend-2
+ spec:
+ ports:
+ - port: 9000
+ name: grpc
+ protocol: TCP
+endpointSlices:
+ - apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-grpc-backend
+ namespace: envoy-gateway
+ labels:
+ kubernetes.io/service-name: grpc-backend
+ addressType: IPv4
+ ports:
+ - name: http
+ protocol: TCP
+ port: 8000
+ endpoints:
+ - addresses:
+ - 7.7.7.7
+ conditions:
+ ready: true
+ - apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-grpc-backend-2
+ namespace: default
+ labels:
+ kubernetes.io/service-name: grpc-backend-2
+ addressType: IPv4
+ ports:
+ - name: grpc
+ protocol: TCP
+ port: 9000
+ endpoints:
+ - addresses:
+ - 8.8.8.8
+ conditions:
+ ready: true
+referenceGrants:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: ReferenceGrant
+ metadata:
+ namespace: envoy-gateway
+ name: referencegrant-1
+ spec:
+ from:
+ - group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ namespace: default
+ to:
+ - group: ''
+ kind: Service
+ - group: gateway.envoyproxy.io
+ kind: Backend
+configMaps:
+ - apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: ca-cmap
+ namespace: default
+ data:
+ ca.crt: |
+ -----BEGIN CERTIFICATE-----
+ MIIDJzCCAg+gAwIBAgIUAl6UKIuKmzte81cllz5PfdN2IlIwDQYJKoZIhvcNAQEL
+ BQAwIzEQMA4GA1UEAwwHbXljaWVudDEPMA0GA1UECgwGa3ViZWRiMB4XDTIzMTAw
+ MjA1NDE1N1oXDTI0MTAwMTA1NDE1N1owIzEQMA4GA1UEAwwHbXljaWVudDEPMA0G
+ A1UECgwGa3ViZWRiMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSTc
+ 1yj8HW62nynkFbXo4VXKv2jC0PM7dPVky87FweZcTKLoWQVPQE2p2kLDK6OEszmM
+ yyr+xxWtyiveremrWqnKkNTYhLfYPhgQkczib7eUalmFjUbhWdLvHakbEgCodn3b
+ kz57mInX2VpiDOKg4kyHfiuXWpiBqrCx0KNLpxo3DEQcFcsQTeTHzh4752GV04RU
+ Ti/GEWyzIsl4Rg7tGtAwmcIPgUNUfY2Q390FGqdH4ahn+mw/6aFbW31W63d9YJVq
+ ioyOVcaMIpM5B/c7Qc8SuhCI1YGhUyg4cRHLEw5VtikioyE3X04kna3jQAj54YbR
+ bpEhc35apKLB21HOUQIDAQABo1MwUTAdBgNVHQ4EFgQUyvl0VI5vJVSuYFXu7B48
+ 6PbMEAowHwYDVR0jBBgwFoAUyvl0VI5vJVSuYFXu7B486PbMEAowDwYDVR0TAQH/
+ BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAMLxrgFVMuNRq2wAwcBt7SnNR5Cfz
+ 2MvXq5EUmuawIUi9kaYjwdViDREGSjk7JW17vl576HjDkdfRwi4E28SydRInZf6J
+ i8HZcZ7caH6DxR335fgHVzLi5NiTce/OjNBQzQ2MJXVDd8DBmG5fyatJiOJQ4bWE
+ A7FlP0RdP3CO3GWE0M5iXOB2m1qWkE2eyO4UHvwTqNQLdrdAXgDQlbam9e4BG3Gg
+ d/6thAkWDbt/QNT+EJHDCvhDRKh1RuGHyg+Y+/nebTWWrFWsktRrbOoHCZiCpXI1
+ 3eXE6nt0YkgtDxG22KqnhpAg9gUSs2hlhoxyvkzyF0mu6NhPlwAgnq7+/Q==
+ -----END CERTIFICATE-----
+backendTLSPolicies:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-grpc
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: ''
+ kind: Service
+ name: grpc-backend
+ sectionName: grpc
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: grpc-backend
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-backend-ip
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: ip-backend
+envoyExtensionPolicies:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ extProc:
+ - backendRefs:
+ - Name: grpc-backend
+ Namespace: envoy-gateway
+ Port: 8000
+ - Name: grpc-backend-2
+ Port: 9000
+ fallback: true
+ - Name: backend-ip
+ Kind: Backend
+ Group: gateway.envoyproxy.io
+ fallback: true
+ - Name: backend-ip-tls
+ Namespace: envoy-gateway
+ Kind: Backend
+ Group: gateway.envoyproxy.io
+ fallback: true
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
diff --git a/internal/gatewayapi/testdata/envoyproxy-priority-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-priority-backend.out.yaml
new file mode 100644
index 00000000000..8044e3874ed
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-priority-backend.out.yaml
@@ -0,0 +1,383 @@
+backendTLSPolicies:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-grpc
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: ""
+ kind: Service
+ name: grpc-backend
+ sectionName: grpc
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: grpc-backend
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ name: policy-for-http-route
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-backend-ip
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: ip-backend
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ name: policy-for-http-route
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+envoyExtensionPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route
+ namespace: default
+ spec:
+ extProc:
+ - backendRefs:
+ - name: grpc-backend
+ namespace: envoy-gateway
+ port: 8000
+ - fallback: true
+ name: grpc-backend-2
+ port: 9000
+ - fallback: true
+ group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - fallback: true
+ group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /bar
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+infraIR:
+ default/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-1
+xdsIR:
+ default/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ envoyExtensions:
+ extProcs:
+ - authority: grpc-backend.envoy-gateway:8000
+ destination:
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ settings:
+ - addressType: IP
+ protocol: GRPC
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-grpc/envoy-gateway-ca
+ sni: grpc-backend
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 9000
+ priority: 1
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ priority: 1
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3443
+ priority: 1
+ protocol: GRPC
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sni: ip-backend
+ weight: 1
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/gatewayapi/testdata/envoyproxy-service-routing-for-gateway.out.yaml b/internal/gatewayapi/testdata/envoyproxy-service-routing-for-gateway.out.yaml
old mode 100755
new mode 100644
diff --git a/internal/gatewayapi/testdata/envoyproxy-service-routing.out.yaml b/internal/gatewayapi/testdata/envoyproxy-service-routing.out.yaml
old mode 100755
new mode 100644
diff --git a/internal/gatewayapi/testdata/envoyproxy-tls-settings-invalid-ns.out.yaml b/internal/gatewayapi/testdata/envoyproxy-tls-settings-invalid-ns.out.yaml
index d5cdc135857..306302e68e1 100644
--- a/internal/gatewayapi/testdata/envoyproxy-tls-settings-invalid-ns.out.yaml
+++ b/internal/gatewayapi/testdata/envoyproxy-tls-settings-invalid-ns.out.yaml
@@ -20,7 +20,7 @@ backendTLSPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: 'Client authentication TLS secret is not located in the same namespace
+ message: 'ClientCertificateRef Secret is not located in the same namespace
as Envoyproxy. Secret namespace: envoy-gateway-user-ns does not match Envoyproxy
namespace: envoy-gateway-system.'
reason: Invalid
@@ -209,9 +209,11 @@ tcpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: Route is accepted
- reason: Accepted
- status: "True"
+ message: 'ClientCertificateRef Secret is not located in the same namespace
+ as Envoyproxy. Secret namespace: envoy-gateway-user-ns does not match Envoyproxy
+ namespace: envoy-gateway-system'
+ reason: Failed to process the settings associated with the TCP route.
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: Resolved all the Object references for the Route
@@ -242,32 +244,8 @@ xdsIR:
mergeSlashes: true
port: 10443
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-tls/rule/0
- settings:
- - addressType: IP
- endpoints:
- - host: 10.244.0.11
- port: 443
- protocol: HTTP
- tls:
- alpnProtocols:
- - HTTP/1.1
- - HTTP/2
- ciphers:
- - ECDHE-RSA-AES128-GCM-SHA256
- - ECDHE-ECDSA-AES256-GCM-SHA384
- ecdhCurves:
- - ECDHE-RSA-AES128-GCM-SHA256
- - ECDHE-ECDSA-AES256-GCM-SHA384
- maxVersion: tls1.3
- minVersion: tls1.2
- signatureAlgorithms:
- - RSA-PSS-RSAE-SHA256
- - ECDSA-SECP256R1-SHA256
- sni: example.com
- useSystemTrustStore: true
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
@@ -276,50 +254,18 @@ xdsIR:
namespace: envoy-gateway
name: httproute/envoy-gateway/httproute-tls/rule/0/match/-1/*
tls:
+ alpnProtocols: null
certificates:
- name: envoy-gateway/default-cert
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
tcp:
- address: 0.0.0.0
name: envoy-gateway/gateway-tls/
port: 10445
- routes:
- - destination:
- name: tcproute/envoy-gateway/envoy-gateway/rule/-1
- settings:
- - addressType: IP
- endpoints:
- - host: 10.244.0.11
- port: 443
- protocol: TCP
- tls:
- alpnProtocols:
- - HTTP/1.1
- - HTTP/2
- ciphers:
- - ECDHE-RSA-AES128-GCM-SHA256
- - ECDHE-ECDSA-AES256-GCM-SHA384
- ecdhCurves:
- - ECDHE-RSA-AES128-GCM-SHA256
- - ECDHE-ECDSA-AES256-GCM-SHA384
- maxVersion: tls1.3
- minVersion: tls1.2
- signatureAlgorithms:
- - RSA-PSS-RSAE-SHA256
- - ECDSA-SECP256R1-SHA256
- sni: example.com
- useSystemTrustStore: true
- weight: 1
- name: tcproute/envoy-gateway/envoy-gateway
- tls:
- terminate:
- certificates:
- - name: envoy-gateway/default-cert
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
- serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
tls:
+ alpnProtocols: []
certificates:
- name: envoy-gateway/default-cert
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
diff --git a/internal/gatewayapi/testdata/envoyproxy-tls-settings-invalid.out.yaml b/internal/gatewayapi/testdata/envoyproxy-tls-settings-invalid.out.yaml
index b949e8af176..2078ceeb703 100644
--- a/internal/gatewayapi/testdata/envoyproxy-tls-settings-invalid.out.yaml
+++ b/internal/gatewayapi/testdata/envoyproxy-tls-settings-invalid.out.yaml
@@ -20,8 +20,8 @@ backendTLSPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: 'Failed to locate TLS secret for client auth: client-auth-not-found
- in namespace: envoy-gateway-system.'
+ message: 'Failed to locate TLS secret for client auth: envoy-gateway-system/client-auth-not-found
+ specified in EnvoyProxy envoy-gateway-system/test.'
reason: Invalid
status: "False"
type: Accepted
@@ -208,9 +208,10 @@ tcpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: Route is accepted
- reason: Accepted
- status: "True"
+ message: 'failed to locate TLS secret for client auth: envoy-gateway-system/client-auth-not-found
+ specified in EnvoyProxy envoy-gateway-system/test'
+ reason: Failed to process the settings associated with the TCP route.
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: Resolved all the Object references for the Route
@@ -241,32 +242,8 @@ xdsIR:
mergeSlashes: true
port: 10443
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-tls/rule/0
- settings:
- - addressType: IP
- endpoints:
- - host: 10.244.0.11
- port: 443
- protocol: HTTP
- tls:
- alpnProtocols:
- - HTTP/1.1
- - HTTP/2
- ciphers:
- - ECDHE-RSA-AES128-GCM-SHA256
- - ECDHE-ECDSA-AES256-GCM-SHA384
- ecdhCurves:
- - ECDHE-RSA-AES128-GCM-SHA256
- - ECDHE-ECDSA-AES256-GCM-SHA384
- maxVersion: tls1.3
- minVersion: tls1.2
- signatureAlgorithms:
- - RSA-PSS-RSAE-SHA256
- - ECDSA-SECP256R1-SHA256
- sni: example.com
- useSystemTrustStore: true
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
@@ -275,50 +252,18 @@ xdsIR:
namespace: envoy-gateway
name: httproute/envoy-gateway/httproute-tls/rule/0/match/-1/*
tls:
+ alpnProtocols: null
certificates:
- name: envoy-gateway/default-cert
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
tcp:
- address: 0.0.0.0
name: envoy-gateway/gateway-tls/
port: 10445
- routes:
- - destination:
- name: tcproute/envoy-gateway/envoy-gateway/rule/-1
- settings:
- - addressType: IP
- endpoints:
- - host: 10.244.0.11
- port: 443
- protocol: TCP
- tls:
- alpnProtocols:
- - HTTP/1.1
- - HTTP/2
- ciphers:
- - ECDHE-RSA-AES128-GCM-SHA256
- - ECDHE-ECDSA-AES256-GCM-SHA384
- ecdhCurves:
- - ECDHE-RSA-AES128-GCM-SHA256
- - ECDHE-ECDSA-AES256-GCM-SHA384
- maxVersion: tls1.3
- minVersion: tls1.2
- signatureAlgorithms:
- - RSA-PSS-RSAE-SHA256
- - ECDSA-SECP256R1-SHA256
- sni: example.com
- useSystemTrustStore: true
- weight: 1
- name: tcproute/envoy-gateway/envoy-gateway
- tls:
- terminate:
- certificates:
- - name: envoy-gateway/default-cert
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
- serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
tls:
+ alpnProtocols: []
certificates:
- name: envoy-gateway/default-cert
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
diff --git a/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml b/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml
index 2913349045c..e65df0254f4 100644
--- a/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml
+++ b/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml
@@ -257,7 +257,7 @@ xdsIR:
- ECDHE-ECDSA-AES256-GCM-SHA384
clientCertificates:
- name: envoy-gateway-system/client-auth
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
ecdhCurves:
- ECDHE-RSA-AES128-GCM-SHA256
@@ -278,9 +278,10 @@ xdsIR:
namespace: envoy-gateway
name: httproute/envoy-gateway/httproute-tls/rule/0/match/-1/*
tls:
+ alpnProtocols: null
certificates:
- name: envoy-gateway/default-cert
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
tcp:
- address: 0.0.0.0
@@ -304,7 +305,7 @@ xdsIR:
- ECDHE-ECDSA-AES256-GCM-SHA384
clientCertificates:
- name: envoy-gateway-system/client-auth
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
ecdhCurves:
- ECDHE-RSA-AES128-GCM-SHA256
@@ -320,12 +321,14 @@ xdsIR:
name: tcproute/envoy-gateway/envoy-gateway
tls:
terminate:
+ alpnProtocols: []
certificates:
- name: envoy-gateway/default-cert
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
tls:
+ alpnProtocols: []
certificates:
- name: envoy-gateway/default-cert
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
diff --git a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml
index 9cd3485cec3..4c06c534135 100644
--- a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml
+++ b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml
@@ -9,6 +9,33 @@ envoyProxyForGatewayClass:
tracing:
samplingRate: 100
provider:
+ backendSettings:
+ http2:
+ initialStreamWindowSize: 128Ki
+ initialConnectionWindowSize: 2Mi
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ type: ConsistentHash
+ consistentHash:
+ type: Header
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ circuitBreaker:
+ maxConnections: 2048
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ connection:
+ bufferLimit: 20Mi
backendRefs:
- name: otel-collector
namespace: monitoring
diff --git a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml
index 70e07bd18f2..b3a44d78fdc 100644
--- a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml
+++ b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml
@@ -106,6 +106,33 @@ infraIR:
- name: otel-collector
namespace: monitoring
port: 4317
+ backendSettings:
+ circuitBreaker:
+ maxConnections: 2048
+ connection:
+ bufferLimit: 20Mi
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 2Mi
+ initialStreamWindowSize: 128Ki
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ type: Header
+ type: ConsistentHash
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
type: OpenTelemetry
samplingRate: 100
status: {}
@@ -156,6 +183,58 @@ xdsIR:
- name: otel-collector
namespace: monitoring
port: 4317
+ backendSettings:
+ circuitBreaker:
+ maxConnections: 2048
+ connection:
+ bufferLimit: 20Mi
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 2Mi
+ initialStreamWindowSize: 128Ki
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ type: Header
+ type: ConsistentHash
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
type: OpenTelemetry
samplingRate: 100
serviceName: gateway-1.envoy-gateway
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 131072
+ initialStreamWindowSize: 2097152
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
diff --git a/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.in.yaml b/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.in.yaml
new file mode 100644
index 00000000000..8fba772492e
--- /dev/null
+++ b/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.in.yaml
@@ -0,0 +1,65 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: empty-hostname
+ port: 80
+ protocol: HTTP
+ allowedRoutes:
+ namespaces:
+ from: All
+ - name: wildcard-example-com
+ port: 80
+ protocol: HTTP
+ hostname: "*.example.com"
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-1
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: empty-hostname
+ hostnames:
+ - "bar.com"
+ - "*.example.com" # request matching is prevented by the isolation wildcard-example-com listener
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /empty-hostname
+ backendRefs:
+ - name: service-1
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-2
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: wildcard-example-com
+ hostnames:
+ - "bar.com" # doesn't match wildcard-example-com listener
+ - "*.example.com"
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /wildcard-example-com
+ backendRefs:
+ - name: service-1
+ port: 8080
diff --git a/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.out.yaml b/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.out.yaml
new file mode 100644
index 00000000000..ce41660893b
--- /dev/null
+++ b/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.out.yaml
@@ -0,0 +1,230 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: empty-hostname
+ port: 80
+ protocol: HTTP
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.example.com'
+ name: wildcard-example-com
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: empty-hostname
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: wildcard-example-com
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - bar.com
+ - '*.example.com'
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: empty-hostname
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ type: PathPrefix
+ value: /empty-hostname
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Service envoy-gateway/service-1 not found
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: empty-hostname
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - bar.com
+ - '*.example.com'
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: wildcard-example-com
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ type: PathPrefix
+ value: /wildcard-example-com
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Service envoy-gateway/service-1 not found
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: wildcard-example-com
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/empty-hostname
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: empty-hostname
+ name: envoy-gateway/gateway-1/empty-hostname
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - directResponse:
+ statusCode: 500
+ hostname: bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-1/rule/0/match/0/bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /empty-hostname
+ - address: 0.0.0.0
+ hostnames:
+ - '*.example.com'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: wildcard-example-com
+ name: envoy-gateway/gateway-1/wildcard-example-com
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - directResponse:
+ statusCode: 500
+ hostname: '*.example.com'
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-2/rule/0/match/0/*_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /wildcard-example-com
diff --git a/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml b/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml
index 2cbe1ecc667..0b38b962b89 100644
--- a/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml
@@ -150,7 +150,8 @@ xdsIR:
name: ""
prefix: /
tls:
+ alpnProtocols: null
certificates:
- name: default/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml
index 866ca1e861a..64e9d93ead0 100644
--- a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml
@@ -72,9 +72,10 @@ tcpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: Route is accepted
- reason: Accepted
- status: "True"
+ message: 'backend service validation failed: TCP Port 8081 not found on service
+ default/service-1'
+ reason: Failed to process the settings associated with the TCP route.
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: TCP Port 8081 not found on service default/service-1
@@ -94,9 +95,3 @@ xdsIR:
- address: 0.0.0.0
name: envoy-gateway/gateway-1/tcp
port: 10162
- routes:
- - destination:
- name: tcproute/default/tcproute-1/rule/-1
- settings:
- - weight: 1
- name: tcproute/default/tcproute-1
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml
index 73cd302aa02..6e35700c58e 100644
--- a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml
@@ -139,7 +139,8 @@ xdsIR:
name: ""
prefix: /
tls:
+ alpnProtocols: null
certificates:
- name: default/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml
index 465408282d9..9e2db8004e5 100644
--- a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml
@@ -208,9 +208,10 @@ xdsIR:
name: ""
prefix: /
tls:
+ alpnProtocols: null
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tcp:
- address: 0.0.0.0
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml
index 03cf19502d7..2e62a910d44 100644
--- a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml
@@ -72,9 +72,10 @@ udpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: Route is accepted
- reason: Accepted
- status: "True"
+ message: 'backend service validation failed: UDP Port 8080 not found on service
+ default/service-1'
+ reason: Failed to process the settings associated with the UDP route.
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: UDP Port 8080 not found on service default/service-1
@@ -94,9 +95,3 @@ xdsIR:
- address: 0.0.0.0
name: envoy-gateway/gateway-1/udp
port: 10162
- route:
- destination:
- name: udproute/default/udproute-1/rule/-1
- settings:
- - weight: 1
- name: udproute/default/udproute-1
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-unsupported-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-unsupported-protocol.out.yaml
index 123a0171cb6..0875ec2454d 100644
--- a/internal/gatewayapi/testdata/gateway-with-listener-with-unsupported-protocol.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-with-listener-with-unsupported-protocol.out.yaml
@@ -34,7 +34,7 @@ gateways:
status: "True"
type: ResolvedRefs
name: unsupported
- supportedKinds: null
+ supportedKinds: []
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml
index 44d08629515..a9939722a0d 100644
--- a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml
@@ -141,10 +141,11 @@ xdsIR:
name: ""
prefix: /
tls:
+ alpnProtocols: null
certificates:
- name: envoy-gateway/tls-secret-ecdsa-1
- privateKey: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUxEbnZNM1RKM3NHYm9EeTF4T3dqSVppVFNWeWZXVWF5YVExcWdrdUdacEtvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFSDVWdHJjenJQS091alV5RTMyaDU2UnVrdHUzSVhTVnJJMkNibXh5UUpqcEY3di9rNVNqTQpSVXZjUnBCdmpnQWROaGhUNGNUMXV4YW1TMFlmQ2JXMVhRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJnVENDQVNlZ0F3SUJBZ0lVRm1sOExCRzBvL1FLNFErWjdrODI0c0MyaUZ3d0NnWUlLb1pJemowRUF3SXcKRmpFVU1CSUdBMVVFQXd3TFptOXZMbUpoY2k1amIyMHdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVdNUlF3RWdZRFZRUUREQXRtYjI4dVltRnlMbU52YlRCWk1CTUdCeXFHU000OUFnRUdDQ3FHClNNNDlBd0VIQTBJQUJMYVl2cUt1VlZveERvNTJlV3p2WUI1anc3RU1GODZybXlvaTVadWF5emRNdnBnNHpCcjgKUktCak5zK1QxakI4T0t1Y1MvN1JVRHgwcHorOTc2ek0zaU9qVXpCUk1CMEdBMVVkRGdRV0JCVE82K2NnMFIwZAp3dHJ6SlFQRzZnNzZoQkJVelRBZkJnTlZIU01FR0RBV2dCVE82K2NnMFIwZHd0cnpKUVBHNmc3NmhCQlV6VEFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFDMlhwUFFnUXpXYWUzYjVwWnQKR2N1TWZESjBjME9QS2NuZWdrWFoyQzRCM2dJZ1Uvc1Jrd0lwTFFOUlYrRWFZdzRQNVQ1Z1BFNlkrVnBtQzk4aApvVmpaL3pRPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t
- name: envoy-gateway/tls-secret-ecdsa-2
- privateKey: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1JR2tBZ0VCQkRDUUE5VWo0SkR5c0Q0MlJIMGI2cjU5NTlXTmlXU2ZKZlMxK2RvTjk0TzZCUGdaQUJiUTI4eTIKUTZsM3pZdklLeFNnQndZRks0RUVBQ0toWkFOaUFBUjR5MGNMZUVoNnJaQ3gyUzFLTDlrMUg4d28xcTlLYmNjMgpmdTBhaUIrcHFxZndCS0FjaHJ2SlJUNzQreWdNUHFSLzc0Sjd1NngzU1pBN1ZLZDFnaGFQWkF1SWpQUTFrZndICjlDdmlMc25RZ3JDeENWU2U2ZG1xL2twajFNdEJyU2M9Ci0tLS0tRU5EIEVDIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJ5RENDQVU2Z0F3SUJBZ0lVUWltVUFlSExNdHo0dEdSdG5oNG9qWHRhVXpzd0NnWUlLb1pJemowRUF3SXcKR3pFWk1CY0dBMVVFQXd3UWRHVnpkQzVsZUdGdGNHeGxMbU52YlRBZUZ3MHlOREExTWpVd09URXhNemRhRncwegpOREExTWpNd09URXhNemRhTUJzeEdUQVhCZ05WQkFNTUVIUmxjM1F1WlhoaGJYQnNaUzVqYjIwd2RqQVFCZ2NxCmhrak9QUUlCQmdVcmdRUUFJZ05pQUFSNHkwY0xlRWg2clpDeDJTMUtMOWsxSDh3bzFxOUtiY2MyZnUwYWlCK3AKcXFmd0JLQWNocnZKUlQ3NCt5Z01QcVIvNzRKN3U2eDNTWkE3VktkMWdoYVBaQXVJalBRMWtmd0g5Q3ZpTHNuUQpnckN4Q1ZTZTZkbXEva3BqMU10QnJTZWpVekJSTUIwR0ExVWREZ1FXQkJUYVNlb1RtY3JlRU5Kd0t5ZmlZS3JnCjlIdnFVREFmQmdOVkhTTUVHREFXZ0JUYVNlb1RtY3JlRU5Kd0t5ZmlZS3JnOUh2cVVEQVBCZ05WSFJNQkFmOEUKQlRBREFRSC9NQW9HQ0NxR1NNNDlCQU1DQTJnQU1HVUNNRzFPSlUrRTlEaCt4TjdJMFZVTXIwdmt3S0h6V2Q3NwpTQXFXQjJVcG4vNThQTzd3eWNvWHZNMjlwREU0SkUvRzVRSXhBT2FhemxKZ1M3Z081eU50aW1tZ0llWFJ1K2pwCkNXb3kxb3hZU2ZSMmh1YkJ1Q1RUUkFqNkhPODBjTUVrZHFrMWp3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml
index 8db9361d4be..6fdbe779e25 100644
--- a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml
@@ -141,10 +141,11 @@ xdsIR:
name: ""
prefix: /
tls:
+ alpnProtocols: null
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
- name: envoy-gateway/tls-secret-ecdsa-1
- privateKey: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUxEbnZNM1RKM3NHYm9EeTF4T3dqSVppVFNWeWZXVWF5YVExcWdrdUdacEtvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFSDVWdHJjenJQS091alV5RTMyaDU2UnVrdHUzSVhTVnJJMkNibXh5UUpqcEY3di9rNVNqTQpSVXZjUnBCdmpnQWROaGhUNGNUMXV4YW1TMFlmQ2JXMVhRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJnVENDQVNlZ0F3SUJBZ0lVRm1sOExCRzBvL1FLNFErWjdrODI0c0MyaUZ3d0NnWUlLb1pJemowRUF3SXcKRmpFVU1CSUdBMVVFQXd3TFptOXZMbUpoY2k1amIyMHdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVdNUlF3RWdZRFZRUUREQXRtYjI4dVltRnlMbU52YlRCWk1CTUdCeXFHU000OUFnRUdDQ3FHClNNNDlBd0VIQTBJQUJMYVl2cUt1VlZveERvNTJlV3p2WUI1anc3RU1GODZybXlvaTVadWF5emRNdnBnNHpCcjgKUktCak5zK1QxakI4T0t1Y1MvN1JVRHgwcHorOTc2ek0zaU9qVXpCUk1CMEdBMVVkRGdRV0JCVE82K2NnMFIwZAp3dHJ6SlFQRzZnNzZoQkJVelRBZkJnTlZIU01FR0RBV2dCVE82K2NnMFIwZHd0cnpKUVBHNmc3NmhCQlV6VEFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFDMlhwUFFnUXpXYWUzYjVwWnQKR2N1TWZESjBjME9QS2NuZWdrWFoyQzRCM2dJZ1Uvc1Jrd0lwTFFOUlYrRWFZdzRQNVQ1Z1BFNlkrVnBtQzk4aApvVmpaL3pRPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml
index 9bcaa10ec80..680ff1bf524 100644
--- a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml
@@ -138,7 +138,8 @@ xdsIR:
name: ""
prefix: /
tls:
+ alpnProtocols: null
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
diff --git a/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml b/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml
index cedcb828721..bafbb34668b 100644
--- a/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml
@@ -138,7 +138,8 @@ xdsIR:
name: ""
prefix: /
tls:
+ alpnProtocols: null
certificates:
- name: default/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
diff --git a/internal/gatewayapi/testdata/grpcroute-with-backend.in.yaml b/internal/gatewayapi/testdata/grpcroute-with-backend.in.yaml
index a02496321ec..d4fec0ea572 100644
--- a/internal/gatewayapi/testdata/grpcroute-with-backend.in.yaml
+++ b/internal/gatewayapi/testdata/grpcroute-with-backend.in.yaml
@@ -36,6 +36,7 @@ grpcRoutes:
- group: gateway.envoyproxy.io
kind: Backend
name: backend-ip
+ name: grpcrule-1
backends:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
diff --git a/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml
index 12bc6d3e1db..1d7cb30742e 100644
--- a/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml
+++ b/internal/gatewayapi/testdata/grpcroute-with-backend.out.yaml
@@ -16,7 +16,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -82,6 +82,7 @@ grpcRoutes:
- method:
service: com.[A-Z]+
type: RegularExpression
+ name: grpcrule-1
status:
parents:
- conditions:
@@ -138,11 +139,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: grpcroute/default/grpcroute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: true
@@ -150,16 +147,13 @@ xdsIR:
kind: GRPCRoute
name: grpcroute-1
namespace: default
+ sectionName: grpcrule-1
name: grpcroute/default/grpcroute-1/rule/0/match/1/*
pathMatch:
distinct: false
name: ""
safeRegex: /com.[A-Z]+/[A-Za-z_][A-Za-z_0-9]*
- - destination:
- name: grpcroute/default/grpcroute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: true
@@ -167,6 +161,7 @@ xdsIR:
kind: GRPCRoute
name: grpcroute-1
namespace: default
+ sectionName: grpcrule-1
name: grpcroute/default/grpcroute-1/rule/0/match/0/*
pathMatch:
distinct: false
diff --git a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.in.yaml b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.in.yaml
index 2c48dad582e..29fcb5a75a1 100644
--- a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.in.yaml
+++ b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.in.yaml
@@ -26,6 +26,11 @@ grpcRoutes:
sectionName: http
rules:
- filters:
+ - type: "RequestHeaderModifier"
+ requestHeaderModifier:
+ add:
+ - name: "my-header-multi-value"
+ value: "foo,bar"
- type: "RequestHeaderModifier"
requestHeaderModifier:
add:
diff --git a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml
index f36c9c969cc..110d404c44f 100644
--- a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml
+++ b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml
@@ -56,6 +56,11 @@ grpcRoutes:
- name: service-1
port: 8080
filters:
+ - requestHeaderModifier:
+ add:
+ - name: my-header-multi-value
+ value: foo,bar
+ type: RequestHeaderModifier
- requestHeaderModifier:
add:
- name: my-header
@@ -117,9 +122,15 @@ xdsIR:
port: 10080
routes:
- addRequestHeaders:
+ - append: true
+ name: my-header-multi-value
+ value:
+ - foo
+ - bar
- append: true
name: my-header
- value: foo
+ value:
+ - foo
destination:
name: grpcroute/default/grpcroute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml
index 8a7e9838848..6cbe82eca0a 100644
--- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml
@@ -158,6 +158,8 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
+ directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
@@ -169,7 +171,4 @@ xdsIR:
distinct: false
name: ""
prefix: /
- traffic:
- timeout:
- http:
- requestTimeout: 1s
+ timeout: 1s
diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml
index 8852171648d..60c001200b9 100644
--- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml
@@ -332,6 +332,7 @@ xdsIR:
distinct: false
name: ""
prefix: /
+ timeout: 1s
traffic:
timeout:
http:
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml
index 228a1d80a2a..2b7899d4f75 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml
@@ -209,7 +209,8 @@ xdsIR:
name: ""
prefix: /
tls:
+ alpnProtocols: null
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
index 735622c4041..484fe119154 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
@@ -15,7 +15,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -33,7 +33,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -51,7 +51,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
index c93f3cbe72d..64b578f98b5 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
@@ -18,7 +18,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -38,7 +38,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -59,7 +59,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -80,7 +80,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -274,11 +274,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
@@ -291,16 +287,8 @@ xdsIR:
distinct: false
name: ""
prefix: /1
- - destination:
- name: httproute/default/httproute-3/rule/0
- settings:
- - addressType: Mixed
- endpoints:
- - host: primary.foo.com
- port: 3000
- - host: 1.1.1.1
- port: 3001
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
@@ -312,16 +300,8 @@ xdsIR:
distinct: false
name: ""
prefix: /3
- - destination:
- name: httproute/default/httproute-2/rule/0
- settings:
- - addressType: Mixed
- endpoints:
- - host: primary.foo.com
- port: 3000
- - host: 1.1.1.1
- port: 3001
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
index b25d2af5d90..c252ac4d77f 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
@@ -15,7 +15,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -33,7 +33,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -51,7 +51,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -70,7 +70,7 @@ backends:
range is not supported'
reason: Accepted
status: "False"
- type: Accepted
+ type: Invalid
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -89,7 +89,7 @@ backends:
with at least two segments separated by dots'
reason: Accepted
status: "False"
- type: Accepted
+ type: Invalid
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -272,9 +272,10 @@ httpRoutes:
status: "True"
type: Accepted
- lastTransitionTime: null
- message: Resolved all the Object references for the Route
- reason: ResolvedRefs
- status: "True"
+ message: Invalid Backend reference to Backend default/backend-ip-localhost
+ found
+ reason: UnsupportedRefAddressFound
+ status: "False"
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
@@ -309,9 +310,10 @@ httpRoutes:
status: "True"
type: Accepted
- lastTransitionTime: null
- message: Resolved all the Object references for the Route
- reason: ResolvedRefs
- status: "True"
+ message: Invalid Backend reference to Backend default/backend-fqdn-localhost
+ found
+ reason: UnsupportedRefAddressFound
+ status: "False"
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
@@ -355,11 +357,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
@@ -410,14 +408,8 @@ xdsIR:
distinct: false
name: ""
prefix: /2
- - destination:
- name: httproute/default/httproute-4/rule/0
- settings:
- - addressType: IP
- endpoints:
- - host: 127.0.0.1
- port: 3001
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
@@ -429,14 +421,8 @@ xdsIR:
distinct: false
name: ""
prefix: /4
- - destination:
- name: httproute/default/httproute-5/rule/0
- settings:
- - addressType: FQDN
- endpoints:
- - host: localhost
- port: 3001
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml
index 68dd071124b..86255af66ce 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-diff-address-type.out.yaml
@@ -15,7 +15,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -33,7 +33,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -51,7 +51,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -296,20 +296,8 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- - addressType: IP
- endpoints:
- - host: 1.1.1.1
- port: 3001
- weight: 1
- - addressType: FQDN
- endpoints:
- - host: primary.foo.com
- port: 3000
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
@@ -321,15 +309,8 @@ xdsIR:
distinct: false
name: ""
prefix: /1
- - destination:
- name: httproute/default/httproute-2/rule/0
- settings:
- - weight: 1
- - addressType: IP
- endpoints:
- - host: 1.1.1.1
- port: 3001
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
@@ -365,15 +346,8 @@ xdsIR:
distinct: false
name: ""
prefix: /3
- - destination:
- name: httproute/default/httproute-3/rule/0
- settings:
- - weight: 1
- - addressType: FQDN
- endpoints:
- - host: primary.foo.com
- port: 3000
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml
index 7f481247516..c16b8a064ca 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-backend-backendrefs-same-address-type.out.yaml
@@ -15,7 +15,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -33,7 +33,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -51,7 +51,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -68,7 +68,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -86,7 +86,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -104,7 +104,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -305,12 +305,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml
index 38c70c4a8d2..9cf88550489 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml
@@ -115,17 +115,8 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - addressType: Mixed
- endpoints:
- - host: 1.2.3.4
- port: 8080
- - host: foo.bar
- port: 8081
- protocol: HTTP
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml
index c49d551e867..189c968899b 100644
--- a/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml
@@ -135,7 +135,4 @@ xdsIR:
distinct: false
name: ""
prefix: /
- traffic:
- timeout:
- http:
- requestTimeout: 1s
+ timeout: 1s
diff --git a/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml
index dc1c9cb950d..88b1dc893f3 100644
--- a/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml
@@ -135,7 +135,4 @@ xdsIR:
distinct: false
name: ""
prefix: /
- traffic:
- timeout:
- http:
- requestTimeout: 5s
+ timeout: 5s
diff --git a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml
index c02aa5200b4..4c5fcd5e8e2 100644
--- a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-app-protocols.out.yaml
@@ -18,7 +18,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -38,7 +38,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
diff --git a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml
index 195f13d09a4..d56407b0dd9 100644
--- a/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-rule-with-non-service-backends-and-weights.out.yaml
@@ -16,7 +16,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
@@ -34,7 +34,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
diff --git a/internal/gatewayapi/testdata/httproute-with-backendref-add-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-backendref-add-multiple-filters.out.yaml
index 78655fc8476..122d09efdeb 100644
--- a/internal/gatewayapi/testdata/httproute-with-backendref-add-multiple-filters.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-backendref-add-multiple-filters.out.yaml
@@ -147,7 +147,8 @@ xdsIR:
addRequestHeaders:
- append: false
name: add-header-3
- value: some-value
+ value:
+ - some-value
protocol: HTTP
weight: 1
hostname: '*'
@@ -172,10 +173,12 @@ xdsIR:
addRequestHeaders:
- append: true
name: add-header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-2
- value: some-value
+ value:
+ - some-value
protocol: HTTP
weight: 8
- addressType: IP
diff --git a/internal/gatewayapi/testdata/httproute-with-direct-response.in.yaml b/internal/gatewayapi/testdata/httproute-with-direct-response.in.yaml
new file mode 100644
index 00000000000..bd9a316227e
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-direct-response.in.yaml
@@ -0,0 +1,119 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ hostname: "*.envoyproxy.io"
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: direct-response
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /inline
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: direct-response-inline
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /value-ref
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: direct-response-value-ref
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: direct-response-with-errors
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /value-ref-not-found
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: direct-response-value-ref-not-found
+configMaps:
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: value-ref-response
+ namespace: default
+ data:
+ response.body: '{"error": "Internal Server Error"}'
+httpFilters:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: direct-response-inline
+ namespace: default
+ spec:
+ directResponse:
+ contentType: text/plain
+ body:
+ type: Inline
+ inline: "OK"
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: direct-response-value-ref-not-exit
+ namespace: default
+ spec:
+ directResponse:
+ contentType: application/json
+ statusCode: 502
+ body:
+ type: ValueRef
+ valueRef:
+ group: ""
+ kind: ConfigMap
+ name: value-ref-does-not-exist
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: direct-response-value-ref
+ namespace: default
+ spec:
+ directResponse:
+ contentType: application/json
+ statusCode: 502
+ body:
+ type: ValueRef
+ valueRef:
+ group: ""
+ kind: ConfigMap
+ name: value-ref-response
diff --git a/internal/gatewayapi/testdata/httproute-with-direct-response.out.yaml b/internal/gatewayapi/testdata/httproute-with-direct-response.out.yaml
new file mode 100644
index 00000000000..29b6b051366
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-direct-response.out.yaml
@@ -0,0 +1,208 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.envoyproxy.io'
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: direct-response
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: direct-response-inline
+ type: ExtensionRef
+ matches:
+ - path:
+ type: PathPrefix
+ value: /inline
+ - filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: direct-response-value-ref
+ type: ExtensionRef
+ matches:
+ - path:
+ type: PathPrefix
+ value: /value-ref
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: direct-response-with-errors
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: direct-response-value-ref-not-found
+ type: ExtensionRef
+ matches:
+ - path:
+ type: PathPrefix
+ value: /value-ref-not-found
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: 'Unable to translate HTTPRouteFilter: default/direct-response-value-ref-not-found'
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: 'Unable to translate HTTPRouteFilter: default/direct-response-value-ref-not-found'
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*.envoyproxy.io'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - addResponseHeaders:
+ - append: false
+ name: Content-Type
+ value:
+ - application/json
+ directResponse:
+ body: '{"error": "Internal Server Error"}'
+ statusCode: 502
+ hostname: '*.envoyproxy.io'
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: direct-response
+ namespace: default
+ name: httproute/default/direct-response/rule/1/match/0/*_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /value-ref
+ - addResponseHeaders:
+ - append: false
+ name: Content-Type
+ value:
+ - text/plain
+ directResponse:
+ body: OK
+ statusCode: 200
+ hostname: '*.envoyproxy.io'
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: direct-response
+ namespace: default
+ name: httproute/default/direct-response/rule/0/match/0/*_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /inline
diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml
index a86e71b4534..605aa384f3e 100644
--- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml
@@ -134,13 +134,16 @@ xdsIR:
- addRequestHeaders:
- append: true
name: add-header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-2
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-3
- value: some-value
+ value:
+ - some-value
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml
index 39cc44429f6..f122fc17d5b 100644
--- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml
@@ -144,19 +144,24 @@ xdsIR:
- addRequestHeaders:
- append: true
name: Set-Header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-2
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-3
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-5
- value: some-value
+ value:
+ - some-value
- append: false
name: set-header-4
- value: some-value
+ value:
+ - some-value
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml
index b3814e2d41d..67c14e133a7 100644
--- a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml
@@ -128,10 +128,12 @@ xdsIR:
- addRequestHeaders:
- append: true
name: example-header-2
- value: ""
+ value:
+ - ""
- append: false
name: example-header-1
- value: ""
+ value:
+ - ""
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml
index 2ca033356bb..57e337fd1f5 100644
--- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml
@@ -112,11 +112,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml
index e7c2869de1c..c6090f5c196 100644
--- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml
@@ -116,11 +116,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml
index a1c5683d27a..984dc0c98b3 100644
--- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml
@@ -114,11 +114,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml
index ed62f94f257..4274a5f8644 100644
--- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml
@@ -112,11 +112,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml
index 794a5d87c3a..06a77064819 100644
--- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml
@@ -114,11 +114,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml
index 18019d56e70..ae96ef5ed30 100644
--- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml
@@ -112,11 +112,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml
index f9ee3bb21fa..df79cfc2e92 100644
--- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml
@@ -119,11 +119,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml
index 3500d3be9cc..c22e21c8920 100644
--- a/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml
@@ -113,11 +113,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/httproute-with-metadata.in.yaml b/internal/gatewayapi/testdata/httproute-with-metadata.in.yaml
index 24f9fa568ad..c215c01004c 100644
--- a/internal/gatewayapi/testdata/httproute-with-metadata.in.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-metadata.in.yaml
@@ -31,4 +31,13 @@ httpRoutes:
- backendRefs:
- name: service-1
port: 8080
-
+ name: rule-1
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - headers:
+ - type: Exact
+ name: foo
+ value: bar
+ name: rule-2
diff --git a/internal/gatewayapi/testdata/httproute-with-metadata.out.yaml b/internal/gatewayapi/testdata/httproute-with-metadata.out.yaml
old mode 100755
new mode 100644
index 8d86bec237a..9049ebe41de
--- a/internal/gatewayapi/testdata/httproute-with-metadata.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-metadata.out.yaml
@@ -58,6 +58,16 @@ httpRoutes:
- backendRefs:
- name: service-1
port: 8080
+ name: rule-1
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - headers:
+ - name: foo
+ type: Exact
+ value: bar
+ name: rule-2
status:
parents:
- conditions:
@@ -113,6 +123,29 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ headerMatches:
+ - distinct: false
+ exact: bar
+ name: foo
+ hostname: '*'
+ isHTTP2: false
+ metadata:
+ annotations:
+ foo: bar
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ sectionName: rule-2
+ name: httproute/default/httproute-1/rule/1/match/0/*
- destination:
name: httproute/default/httproute-1/rule/0
settings:
@@ -130,4 +163,5 @@ xdsIR:
kind: HTTPRoute
name: httproute-1
namespace: default
+ sectionName: rule-1
name: httproute/default/httproute-1/rule/0/match/-1/*
diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml
index 9aa6f0bf23b..c6e534c9c63 100644
--- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml
@@ -144,13 +144,16 @@ xdsIR:
- addRequestHeaders:
- append: true
name: X-Header-Add
- value: header-val-1
+ value:
+ - header-val-1
- append: true
name: X-Header-Add-Append
- value: header-val-2
+ value:
+ - header-val-2
- append: false
name: X-Header-Set
- value: set-overwrites-values
+ value:
+ - set-overwrites-values
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml
index 50105a1e054..af0ed8f79e7 100644
--- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml
@@ -71,9 +71,10 @@ httpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: Route is accepted
- reason: Accepted
- status: "True"
+ message: 'Error validating backend port: port number not specified for backend
+ reference.'
+ reason: UnsupportedValue
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: A valid port number corresponding to a port on the Service must be
@@ -122,24 +123,3 @@ xdsIR:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 10080
- routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - addressType: IP
- endpoints:
- - host: 7.7.7.7
- port: 8080
- protocol: HTTP
- weight: 1
- hostname: gateway.envoyproxy.io
- isHTTP2: false
- metadata:
- kind: HTTPRoute
- name: httproute-1
- namespace: default
- name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
- pathMatch:
- distinct: false
- name: ""
- prefix: /
diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml
index c0c193e034a..85ff5860d40 100644
--- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml
@@ -72,9 +72,10 @@ httpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: Route is accepted
- reason: Accepted
- status: "True"
+ message: 'Backend service validation failed: Service default/service-unknown
+ not found.'
+ reason: UnsupportedValue
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: Service default/service-unknown not found
@@ -122,24 +123,3 @@ xdsIR:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 10080
- routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - addressType: IP
- endpoints:
- - host: 7.7.7.7
- port: 8080
- protocol: HTTP
- weight: 1
- hostname: gateway.envoyproxy.io
- isHTTP2: false
- metadata:
- kind: HTTPRoute
- name: httproute-1
- namespace: default
- name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
- pathMatch:
- distinct: false
- name: ""
- prefix: /
diff --git a/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-different-ns.in.yaml b/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-different-ns.in.yaml
new file mode 100644
index 00000000000..12aa992ef44
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-different-ns.in.yaml
@@ -0,0 +1,55 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway-a
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: default
+ port: 80
+ protocol: HTTP
+ hostname: '*.a.example.com'
+ allowedRoutes:
+ namespaces:
+ from: All
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway-b
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: default
+ port: 80
+ protocol: HTTP
+ hostname: '*.b.example.com'
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: targeted-route
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - targeted.a.example.com
+ - targeted.b.example.com
+ parentRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-a
+ namespace: default
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-b
+ rules:
+ - matches:
+ - method: GET
+ path:
+ type: PathPrefix
+ value: /toy
diff --git a/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-different-ns.out.yaml b/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-different-ns.out.yaml
new file mode 100644
index 00000000000..ba2f58b8667
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-different-ns.out.yaml
@@ -0,0 +1,249 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-a
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.a.example.com'
+ name: default
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: default
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-b
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.b.example.com'
+ name: default
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: default
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: targeted-route
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - targeted.a.example.com
+ - targeted.b.example.com
+ parentRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-a
+ namespace: default
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-b
+ rules:
+ - matches:
+ - method: GET
+ path:
+ type: PathPrefix
+ value: /toy
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-a
+ namespace: default
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-b
+infraIR:
+ default/gateway-a:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-a/default
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-a
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-a
+ envoy-gateway/gateway-b:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-b/default
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-b
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-b
+xdsIR:
+ default/gateway-a:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*.a.example.com'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-a
+ namespace: default
+ sectionName: default
+ name: default/gateway-a/default
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - directResponse:
+ statusCode: 500
+ headerMatches:
+ - distinct: false
+ exact: GET
+ name: :method
+ hostname: targeted.a.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: targeted-route
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/targeted-route/rule/0/match/0/targeted_a_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /toy
+ envoy-gateway/gateway-b:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*.b.example.com'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-b
+ namespace: envoy-gateway
+ sectionName: default
+ name: envoy-gateway/gateway-b/default
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - directResponse:
+ statusCode: 500
+ headerMatches:
+ - distinct: false
+ exact: GET
+ name: :method
+ hostname: targeted.b.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: targeted-route
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/targeted-route/rule/0/match/0/targeted_b_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /toy
diff --git a/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-same-ns.in.yaml b/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-same-ns.in.yaml
new file mode 100644
index 00000000000..6c9aa71d29c
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-same-ns.in.yaml
@@ -0,0 +1,54 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway-a
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: default
+ port: 80
+ protocol: HTTP
+ hostname: '*.a.example.com'
+ allowedRoutes:
+ namespaces:
+ from: All
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway-b
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: default
+ port: 80
+ protocol: HTTP
+ hostname: '*.b.example.com'
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: targeted-route
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - targeted.a.example.com
+ - targeted.b.example.com
+ parentRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-a
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-b
+ rules:
+ - matches:
+ - method: GET
+ path:
+ type: PathPrefix
+ value: /toy
diff --git a/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-same-ns.out.yaml b/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-same-ns.out.yaml
new file mode 100644
index 00000000000..4e6bef64b9e
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-multiple-gateways-from-same-ns.out.yaml
@@ -0,0 +1,247 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-a
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.a.example.com'
+ name: default
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: default
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-b
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.b.example.com'
+ name: default
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: default
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: targeted-route
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - targeted.a.example.com
+ - targeted.b.example.com
+ parentRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-a
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-b
+ rules:
+ - matches:
+ - method: GET
+ path:
+ type: PathPrefix
+ value: /toy
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-a
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-b
+infraIR:
+ envoy-gateway/gateway-a:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-a/default
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-a
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-a
+ envoy-gateway/gateway-b:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-b/default
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-b
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-b
+xdsIR:
+ envoy-gateway/gateway-a:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*.a.example.com'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-a
+ namespace: envoy-gateway
+ sectionName: default
+ name: envoy-gateway/gateway-a/default
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - directResponse:
+ statusCode: 500
+ headerMatches:
+ - distinct: false
+ exact: GET
+ name: :method
+ hostname: targeted.a.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: targeted-route
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/targeted-route/rule/0/match/0/targeted_a_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /toy
+ envoy-gateway/gateway-b:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*.b.example.com'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-b
+ namespace: envoy-gateway
+ sectionName: default
+ name: envoy-gateway/gateway-b/default
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - directResponse:
+ statusCode: 500
+ headerMatches:
+ - distinct: false
+ exact: GET
+ name: :method
+ hostname: targeted.b.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: targeted-route
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/targeted-route/rule/0/match/0/targeted_b_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /toy
diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml
index 7b53542bdfa..6dcb4b28779 100644
--- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml
@@ -140,19 +140,24 @@ xdsIR:
- addResponseHeaders:
- append: true
name: Set-Header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-2
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-3
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-5
- value: some-value
+ value:
+ - some-value
- append: false
name: set-header-4
- value: some-value
+ value:
+ - some-value
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml
index 459c4264740..47d61c9fcfa 100644
--- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml
@@ -134,13 +134,16 @@ xdsIR:
- addResponseHeaders:
- append: true
name: add-header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-2
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-3
- value: some-value
+ value:
+ - some-value
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml
index d2b4ffbe3f2..1d2f4f7124c 100644
--- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml
@@ -144,19 +144,24 @@ xdsIR:
- addResponseHeaders:
- append: true
name: Set-Header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-2
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-3
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-5
- value: some-value
+ value:
+ - some-value
- append: false
name: set-header-4
- value: some-value
+ value:
+ - some-value
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml
index 9d188a03dc0..723cabbe6f7 100644
--- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml
@@ -128,10 +128,12 @@ xdsIR:
- addResponseHeaders:
- append: true
name: example-header-2
- value: ""
+ value:
+ - ""
- append: false
name: example-header-1
- value: ""
+ value:
+ - ""
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml b/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml
index ff9f5d272a8..37776a693da 100644
--- a/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml
@@ -116,17 +116,8 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/default/httproute-1/rule/0
- settings:
- - weight: 1
- - weight: 1
- - addressType: IP
- endpoints:
- - host: 7.7.7.7
- port: 8080
- protocol: HTTP
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml
index 1577ab27e64..8e3079c9bbe 100644
--- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml
@@ -144,7 +144,8 @@ xdsIR:
name: ""
prefix: /
urlRewrite:
- hostname: rewrite.com
+ host:
+ name: rewrite.com
path:
fullReplace: null
prefixMatchReplace: /rewrite
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml
index 658725825f3..c0d8cce8b8a 100644
--- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml
@@ -141,4 +141,5 @@ xdsIR:
name: ""
prefix: /
urlRewrite:
- hostname: rewrite.com
+ host:
+ name: rewrite.com
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml
index d0d62e98a27..7cbff74f25b 100644
--- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml
@@ -141,4 +141,5 @@ xdsIR:
name: ""
prefix: /
urlRewrite:
- hostname: urlrewrite.envoyproxy.io
+ host:
+ name: urlrewrite.envoyproxy.io
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-http.in.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-http.in.yaml
new file mode 100644
index 00000000000..fd0fea29fd4
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-http.in.yaml
@@ -0,0 +1,147 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ hostname: "*.envoyproxy.io"
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/valid"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/host-and-regex-path"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: URLRewrite
+ urlRewrite:
+ hostname: "rewrite.com"
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-3
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/regex-path-and-host"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+ - type: URLRewrite
+ urlRewrite:
+ hostname: "rewrite.com"
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-missing-substitution
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/missing-substitution"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: missing-substitution
+httpFilters:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: valid
+ namespace: default
+ spec:
+ urlRewrite:
+ path:
+ type: ReplaceRegexMatch
+ replaceRegexMatch:
+ pattern: '.*'
+ substitution: foo
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: missing-substitution
+ namespace: default
+ spec:
+ urlRewrite:
+ path:
+ type: ReplaceRegexMatch
+ replaceRegexMatch:
+ pattern: '.*'
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-http.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-http.out.yaml
new file mode 100644
index 00000000000..c42f3934568
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-http.out.yaml
@@ -0,0 +1,368 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.envoyproxy.io'
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 4
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /valid
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: URLRewrite
+ urlRewrite:
+ hostname: rewrite.com
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /host-and-regex-path
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-3
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+ type: ExtensionRef
+ - type: URLRewrite
+ urlRewrite:
+ hostname: rewrite.com
+ matches:
+ - path:
+ value: /regex-path-and-host
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-missing-substitution
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: missing-substitution
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /missing-substitution
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*.envoyproxy.io'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-missing-substitution/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-missing-substitution
+ namespace: default
+ name: httproute/default/httproute-missing-substitution/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /missing-substitution
+ urlRewrite:
+ path:
+ fullReplace: null
+ prefixMatchReplace: null
+ regexMatchReplace:
+ pattern: .*
+ substitution: ""
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /host-and-regex-path
+ urlRewrite:
+ host:
+ name: rewrite.com
+ path:
+ fullReplace: null
+ prefixMatchReplace: null
+ regexMatchReplace:
+ pattern: .*
+ substitution: foo
+ - destination:
+ name: httproute/default/httproute-3/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-3
+ namespace: default
+ name: httproute/default/httproute-3/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /regex-path-and-host
+ urlRewrite:
+ host:
+ name: rewrite.com
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /valid
+ urlRewrite:
+ path:
+ fullReplace: null
+ prefixMatchReplace: null
+ regexMatchReplace:
+ pattern: .*
+ substitution: foo
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-invalid.in.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-invalid.in.yaml
new file mode 100644
index 00000000000..1ad75975b56
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-invalid.in.yaml
@@ -0,0 +1,230 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ hostname: "*.envoyproxy.io"
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-invalid-pattern
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/invalid-pattern"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: invalid-pattern
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-missing-pattern
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/missing-pattern"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: missing-pattern
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-multiple-path-rewrites-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/ext-first"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+ - type: URLRewrite
+ urlRewrite:
+ path:
+ type: ReplacePrefixMatch
+ replacePrefixMatch: /rewrite
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-multiple-path-rewrites-2
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/inline-first"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: URLRewrite
+ urlRewrite:
+ path:
+ type: ReplacePrefixMatch
+ replacePrefixMatch: /rewrite
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-multiple-regex-path-rewrites
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/two-regex"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-2
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-not-found
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/notfound"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: notfound
+httpFilters:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: valid
+ namespace: default
+ spec:
+ urlRewrite:
+ path:
+ type: ReplaceRegexMatch
+ replaceRegexMatch:
+ pattern: '.*'
+ substitution: foo
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: valid-2
+ namespace: default
+ spec:
+ urlRewrite:
+ path:
+ type: ReplaceRegexMatch
+ replaceRegexMatch:
+ pattern: '.*'
+ substitution: foo
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: invalid-pattern
+ namespace: default
+ spec:
+ urlRewrite:
+ path:
+ type: ReplaceRegexMatch
+ replaceRegexMatch:
+ pattern: '"([a-z]+)"*+?'
+ substitution: foo
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: missing-pattern
+ namespace: default
+ spec:
+ urlRewrite:
+ path:
+ type: ReplaceRegexMatch
+ replaceRegexMatch:
+ substitution: foo
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-invalid.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-invalid.out.yaml
new file mode 100644
index 00000000000..17ffc680f52
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-regex-match-replace-invalid.out.yaml
@@ -0,0 +1,358 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.envoyproxy.io'
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 6
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-invalid-pattern
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: invalid-pattern
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /invalid-pattern
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: ReplaceRegexMatch must be a valid RE2 regular expression
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-missing-pattern
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: missing-pattern
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /missing-pattern
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: ReplaceRegexMatch Pattern must be set when rewrite path type is "ReplaceRegexMatch"
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-multiple-path-rewrites-1
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+ type: ExtensionRef
+ - type: URLRewrite
+ urlRewrite:
+ path:
+ replacePrefixMatch: /rewrite
+ type: ReplacePrefixMatch
+ matches:
+ - path:
+ value: /ext-first
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-multiple-path-rewrites-2
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: URLRewrite
+ urlRewrite:
+ path:
+ replacePrefixMatch: /rewrite
+ type: ReplacePrefixMatch
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /inline-first
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-multiple-regex-path-rewrites
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid
+ type: ExtensionRef
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-2
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /two-regex
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-not-found
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: notfound
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /notfound
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: 'Unable to translate HTTPRouteFilter: default/notfound'
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: 'Unable to translate HTTPRouteFilter: default/notfound'
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*.envoyproxy.io'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.in.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.in.yaml
new file mode 100644
index 00000000000..5a7f4499048
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.in.yaml
@@ -0,0 +1,236 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ hostname: "*.envoyproxy.io"
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-invalid-header
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/invalid-header"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: invalid-header
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-multiple-host-rewrites-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/ext-first"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ - type: URLRewrite
+ urlRewrite:
+ hostname: "rewrite.com"
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-multiple-path-rewrites-2
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/inline-first"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: URLRewrite
+ urlRewrite:
+ hostname: "rewrite.com"
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-multiple-header-host-rewrites
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/two-headers"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header-2
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-multiple-header-host-rewrites
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/two-backends"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-backend
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-backend-2
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-header-and-backend-host-rewrites
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/header-and-backend"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+httpFilters:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: valid-header
+ namespace: default
+ spec:
+ urlRewrite:
+ hostname:
+ type: Header
+ header: my-host
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: valid-header-2
+ namespace: default
+ spec:
+ urlRewrite:
+ hostname:
+ type: Header
+ header: my-host2
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: valid-backend
+ namespace: default
+ spec:
+ urlRewrite:
+ hostname:
+ type: Backend
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: valid-backend-2
+ namespace: default
+ spec:
+ urlRewrite:
+ hostname:
+ type: Backend
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: invalid-header
+ namespace: default
+ spec:
+ urlRewrite:
+ hostname:
+ type: Header
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.out.yaml
new file mode 100644
index 00000000000..ab24ec0e81d
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.out.yaml
@@ -0,0 +1,364 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.envoyproxy.io'
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 6
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-invalid-header
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: invalid-header
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /invalid-header
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Header must be set when rewrite path type is "Header"
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-multiple-host-rewrites-1
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ type: ExtensionRef
+ - type: URLRewrite
+ urlRewrite:
+ hostname: rewrite.com
+ matches:
+ - path:
+ value: /ext-first
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-multiple-path-rewrites-2
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: URLRewrite
+ urlRewrite:
+ hostname: rewrite.com
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /inline-first
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-multiple-header-host-rewrites
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ type: ExtensionRef
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header-2
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /two-headers
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-multiple-header-host-rewrites
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-backend
+ type: ExtensionRef
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-backend-2
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /two-backends
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-header-and-backend-host-rewrites
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ type: ExtensionRef
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /header-and-backend
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule
+ reason: UnsupportedValue
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*.envoyproxy.io'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter.in.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter.in.yaml
new file mode 100644
index 00000000000..f39c951e5f8
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter.in.yaml
@@ -0,0 +1,147 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ hostname: "*.envoyproxy.io"
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/valid-header"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/valid-backend"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-backend
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-3
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/path-and-header-host"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: URLRewrite
+ urlRewrite:
+ path:
+ type: ReplacePrefixMatch
+ replacePrefixMatch: /rewrite
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-4
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/header-host-and-path"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ - type: URLRewrite
+ urlRewrite:
+ path:
+ type: ReplacePrefixMatch
+ replacePrefixMatch: /rewrite
+httpFilters:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: valid-header
+ namespace: default
+ spec:
+ urlRewrite:
+ hostname:
+ type: Header
+ header: my-host
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: HTTPRouteFilter
+ metadata:
+ name: valid-backend
+ namespace: default
+ spec:
+ urlRewrite:
+ hostname:
+ type: Backend
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter.out.yaml
new file mode 100644
index 00000000000..916f7d0cefe
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter.out.yaml
@@ -0,0 +1,362 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.envoyproxy.io'
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 4
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /valid-header
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-backend
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /valid-backend
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-3
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: URLRewrite
+ urlRewrite:
+ path:
+ replacePrefixMatch: /rewrite
+ type: ReplacePrefixMatch
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ type: ExtensionRef
+ matches:
+ - path:
+ value: /path-and-header-host
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-4
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ type: ExtensionRef
+ - type: URLRewrite
+ urlRewrite:
+ path:
+ replacePrefixMatch: /rewrite
+ type: ReplacePrefixMatch
+ matches:
+ - path:
+ value: /header-host-and-path
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*.envoyproxy.io'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-3/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-3
+ namespace: default
+ name: httproute/default/httproute-3/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /path-and-header-host
+ urlRewrite:
+ host:
+ header: my-host
+ path:
+ fullReplace: null
+ prefixMatchReplace: /rewrite
+ - destination:
+ name: httproute/default/httproute-4/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-4
+ namespace: default
+ name: httproute/default/httproute-4/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /header-host-and-path
+ urlRewrite:
+ path:
+ fullReplace: null
+ prefixMatchReplace: /rewrite
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /valid-backend
+ urlRewrite:
+ host:
+ backend: true
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /valid-header
+ urlRewrite:
+ host:
+ header: my-host
diff --git a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml
index 607330a824c..3dc5888bb34 100644
--- a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml
@@ -421,11 +421,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
@@ -459,11 +455,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: grpcroute/envoy-gateway/grpcroute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
headerMatches:
- distinct: false
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-authoriztion.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-client-cidr.in.yaml
similarity index 100%
rename from internal/gatewayapi/testdata/securitypolicy-with-authoriztion.in.yaml
rename to internal/gatewayapi/testdata/securitypolicy-with-authoriztion-client-cidr.in.yaml
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-authoriztion.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-client-cidr.out.yaml
similarity index 100%
rename from internal/gatewayapi/testdata/securitypolicy-with-authoriztion.out.yaml
rename to internal/gatewayapi/testdata/securitypolicy-with-authoriztion-client-cidr.out.yaml
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-jwt-claim.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-jwt-claim.in.yaml
new file mode 100644
index 00000000000..b9aec9c8fd8
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-jwt-claim.in.yaml
@@ -0,0 +1,74 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.example.com
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/foo"
+ backendRefs:
+ - name: service-1
+ port: 8080
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: policy-for-gateway # This policy should attach httproute-2
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ jwt:
+ providers:
+ - name: example1
+ issuer: https://two.example.com
+ audiences:
+ - two.foo.com
+ remoteJWKS:
+ uri: https://two.example.com/jwt/public-key/jwks.json
+ authorization:
+ defaultAction: Deny
+ rules:
+ - name: "allow-jwt-claim"
+ action: Deny
+ principal:
+ jwt:
+ provider: example1
+ scopes:
+ - "foo"
+ - "bar"
+ claims:
+ - name: "sub"
+ values:
+ - "1234567890"
+ - name: "roles"
+ valueType: "StringArray"
+ values:
+ - "admin"
+ - "superuser"
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-jwt-claim.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-jwt-claim.out.yaml
new file mode 100644
index 00000000000..ed422e70031
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-jwt-claim.out.yaml
@@ -0,0 +1,220 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.example.com
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-gateway
+ namespace: envoy-gateway
+ spec:
+ authorization:
+ defaultAction: Deny
+ rules:
+ - action: Deny
+ name: allow-jwt-claim
+ principal:
+ jwt:
+ claims:
+ - name: sub
+ values:
+ - "1234567890"
+ - name: roles
+ valueType: StringArray
+ values:
+ - admin
+ - superuser
+ provider: example1
+ scopes:
+ - foo
+ - bar
+ jwt:
+ providers:
+ - audiences:
+ - two.foo.com
+ issuer: https://two.example.com
+ name: example1
+ remoteJWKS:
+ uri: https://two.example.com/jwt/public-key/jwks.json
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ security:
+ authorization:
+ defaultAction: Deny
+ rules:
+ - action: Deny
+ name: allow-jwt-claim
+ principal:
+ jwt:
+ claims:
+ - name: sub
+ values:
+ - "1234567890"
+ - name: roles
+ valueType: StringArray
+ values:
+ - admin
+ - superuser
+ provider: example1
+ scopes:
+ - foo
+ - bar
+ jwt:
+ providers:
+ - audiences:
+ - two.foo.com
+ issuer: https://two.example.com
+ name: example1
+ remoteJWKS:
+ uri: https://two.example.com/jwt/public-key/jwks.json
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml
index b690cb20370..02fd1a6ddd1 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml
@@ -250,7 +250,7 @@ xdsIR:
security:
basicAuth:
name: securitypolicy/default/policy-for-http-route-1
- users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=
+ users: '[redacted]'
- destination:
name: httproute/default/httproute-1/rule/1
settings:
@@ -274,7 +274,7 @@ xdsIR:
security:
basicAuth:
name: securitypolicy/default/policy-for-http-route-1
- users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=
+ users: '[redacted]'
- destination:
name: httproute/default/httproute-2/rule/0
settings:
@@ -298,4 +298,4 @@ xdsIR:
security:
basicAuth:
name: securitypolicy/default/policy-for-gateway-1
- users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo=
+ users: '[redacted]'
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-cors-targetrefs.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-cors-targetrefs.out.yaml
index 789da05196b..5438cf7dca2 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-cors-targetrefs.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-cors-targetrefs.out.yaml
@@ -354,11 +354,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: grpcroute/envoy-gateway/grpcroute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: '*'
isHTTP2: true
@@ -409,11 +405,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-1/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
@@ -446,11 +438,7 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- name: httproute/envoy-gateway/httproute-2/rule/0
- settings:
- - weight: 1
- directResponse:
+ - directResponse:
statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml
new file mode 100644
index 00000000000..5d756b3b981
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml
@@ -0,0 +1,185 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /foo1
+ backendRefs:
+ - name: service-1
+ port: 8080
+ - matches:
+ - path:
+ value: /foo2
+ backendRefs:
+ - name: service-2
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /bar
+ backendRefs:
+ - name: service-3
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-3
+ spec:
+ hostnames:
+ - www.baz.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /baz
+ backendRefs:
+ - name: service-4
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-4
+ spec:
+ hostnames:
+ - www.qux.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /qux
+ backendRefs:
+ - name: service-5
+ port: 8080
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: 'primary.foo.com'
+ port: 3000
+referenceGrants:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: ReferenceGrant
+ metadata:
+ namespace: envoy-gateway
+ name: referencegrant-1
+ spec:
+ from:
+ - group: gateway.envoyproxy.io
+ kind: SecurityPolicy
+ namespace: default
+ to:
+ - group: ""
+ kind: Service
+securityPolicies:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route-1
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ extAuth:
+ failOpen: true
+ headersToExtAuth:
+ - header1
+ - header2
+ grpc:
+ backendRefs:
+ - name: service-2
+ kind: Service
+ port: 8080
+ - name: backend-fqdn
+ kind: Backend
+ group: gateway.envoyproxy.io
+ port: 3000
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route-3--grpc-backendref
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-3
+ extAuth:
+ failOpen: true
+ headersToExtAuth:
+ - header3
+ - header4
+ grpc:
+ backendRef:
+ name: service-2
+ kind: Service
+ port: 8080
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route-3-http-backendref
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-4
+ extAuth:
+ http:
+ backendRef:
+ name: backend-fqdn
+ kind: Backend
+ group: gateway.envoyproxy.io
+ port: 3000
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml
new file mode 100644
index 00000000000..d5326219c97
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml
@@ -0,0 +1,540 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 4
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo1
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ matches:
+ - path:
+ value: /foo2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-3
+ port: 8080
+ matches:
+ - path:
+ value: /bar
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-3
+ namespace: default
+ spec:
+ hostnames:
+ - www.baz.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-4
+ port: 8080
+ matches:
+ - path:
+ value: /baz
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-4
+ namespace: default
+ spec:
+ hostnames:
+ - www.qux.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-5
+ port: 8080
+ matches:
+ - path:
+ value: /qux
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Service default/service-5 not found
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+infraIR:
+ default/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-1
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route-1
+ namespace: default
+ spec:
+ extAuth:
+ failOpen: true
+ grpc:
+ backendRefs:
+ - kind: Service
+ name: service-2
+ port: 8080
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ port: 3000
+ headersToExtAuth:
+ - header1
+ - header2
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route-3--grpc-backendref
+ namespace: default
+ spec:
+ extAuth:
+ failOpen: true
+ grpc:
+ backendRef:
+ kind: Service
+ name: service-2
+ port: 8080
+ headersToExtAuth:
+ - header3
+ - header4
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-3
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route-3-http-backendref
+ namespace: default
+ spec:
+ extAuth:
+ http:
+ backendRef:
+ group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ port: 3000
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-4
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+xdsIR:
+ default/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo1
+ security:
+ extAuth:
+ failOpen: true
+ grpc:
+ authority: service-2.default:8080
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/extauth/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ name: securitypolicy/default/policy-for-http-route-1
+ - destination:
+ name: httproute/default/httproute-1/rule/1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo2
+ security:
+ extAuth:
+ failOpen: true
+ grpc:
+ authority: service-2.default:8080
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/extauth/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ name: securitypolicy/default/policy-for-http-route-1
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
+ - destination:
+ name: httproute/default/httproute-3/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.baz.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-3
+ namespace: default
+ name: httproute/default/httproute-3/rule/0/match/0/www_baz_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /baz
+ security:
+ extAuth:
+ failOpen: true
+ grpc:
+ authority: service-2.default:8080
+ destination:
+ name: securitypolicy/default/policy-for-http-route-3--grpc-backendref/extauth/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header3
+ - header4
+ name: securitypolicy/default/policy-for-http-route-3--grpc-backendref
+ - directResponse:
+ statusCode: 500
+ hostname: www.qux.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-4
+ namespace: default
+ name: httproute/default/httproute-4/rule/0/match/0/www_qux_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /qux
+ security:
+ extAuth:
+ http:
+ authority: primary.foo.com:3000
+ destination:
+ name: securitypolicy/default/policy-for-http-route-3-http-backendref/extauth/0
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: HTTP
+ weight: 1
+ path: ""
+ name: securitypolicy/default/policy-for-http-route-3-http-backendref
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backendref.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backendref.in.yaml
index e362583125b..1c24de65efe 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backendref.in.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backendref.in.yaml
@@ -145,9 +145,9 @@ securityPolicies:
- header1
- header2
grpc:
- backendRef:
- name: grpc-backend
- port: 9000
+ backendRefs:
+ - name: grpc-backend
+ port: 9000
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
@@ -161,10 +161,10 @@ securityPolicies:
extAuth:
failOpen: false
http:
- backendRef:
- Name: http-backend
- Namespace: envoy-gateway
- Port: 80
+ backendRefs:
+ - Name: http-backend
+ Namespace: envoy-gateway
+ Port: 80
Path: /auth
headersToBackend:
- header1
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backendref.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backendref.out.yaml
index 089e5092072..d72cd182896 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backendref.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backendref.out.yaml
@@ -149,8 +149,8 @@ securityPolicies:
extAuth:
failOpen: true
grpc:
- backendRef:
- name: grpc-backend
+ backendRefs:
+ - name: grpc-backend
port: 9000
headersToExtAuth:
- header1
@@ -184,8 +184,8 @@ securityPolicies:
extAuth:
failOpen: false
http:
- backendRef:
- name: http-backend
+ backendRefs:
+ - name: http-backend
namespace: envoy-gateway
port: 80
headersToBackend:
@@ -263,7 +263,7 @@ xdsIR:
grpc:
authority: grpc-backend.default:9000
destination:
- name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ name: securitypolicy/default/policy-for-http-route-1/extauth/0
settings:
- addressType: IP
endpoints:
@@ -301,7 +301,7 @@ xdsIR:
grpc:
authority: grpc-backend.default:9000
destination:
- name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ name: securitypolicy/default/policy-for-http-route-1/extauth/0
settings:
- addressType: IP
endpoints:
@@ -339,7 +339,7 @@ xdsIR:
http:
authority: http-backend.envoy-gateway:80
destination:
- name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ name: securitypolicy/default/policy-for-gateway-1/extauth/0
settings:
- addressType: IP
endpoints:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.in.yaml
new file mode 100644
index 00000000000..d45b50c8835
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.in.yaml
@@ -0,0 +1,112 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /foo1
+ backendRefs:
+ - name: service-1
+ port: 8080
+ - matches:
+ - path:
+ value: /foo2
+ backendRefs:
+ - name: service-2
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /bar
+ backendRefs:
+ - name: service-3
+ port: 8080
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: 'primary.foo.com'
+ port: 3000
+referenceGrants:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: ReferenceGrant
+ metadata:
+ namespace: envoy-gateway
+ name: referencegrant-1
+ spec:
+ from:
+ - group: gateway.envoyproxy.io
+ kind: SecurityPolicy
+ namespace: default
+ to:
+ - group: ""
+ kind: Service
+securityPolicies:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route-1
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ extAuth:
+ failOpen: true
+ headersToExtAuth:
+ - header1
+ - header2
+ bodyToExtAuth:
+ maxRequestBytes: 32768
+ grpc:
+ backendRefs:
+ - name: service-2
+ kind: Service
+ port: 8080
+ - name: backend-fqdn
+ kind: Backend
+ group: gateway.envoyproxy.io
+ port: 3000
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.out.yaml
new file mode 100644
index 00000000000..ac4dfe7f306
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.out.yaml
@@ -0,0 +1,335 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo1
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ matches:
+ - path:
+ value: /foo2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-3
+ port: 8080
+ matches:
+ - path:
+ value: /bar
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+infraIR:
+ default/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-1
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route-1
+ namespace: default
+ spec:
+ extAuth:
+ bodyToExtAuth:
+ maxRequestBytes: 32768
+ failOpen: true
+ grpc:
+ backendRefs:
+ - kind: Service
+ name: service-2
+ port: 8080
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ port: 3000
+ headersToExtAuth:
+ - header1
+ - header2
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+xdsIR:
+ default/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo1
+ security:
+ extAuth:
+ bodyToExtAuth:
+ maxRequestBytes: 32768
+ failOpen: true
+ grpc:
+ authority: service-2.default:8080
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/extauth/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ name: securitypolicy/default/policy-for-http-route-1
+ - destination:
+ name: httproute/default/httproute-1/rule/1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo2
+ security:
+ extAuth:
+ bodyToExtAuth:
+ maxRequestBytes: 32768
+ failOpen: true
+ grpc:
+ authority: service-2.default:8080
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/extauth/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ name: securitypolicy/default/policy-for-http-route-1
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.in.yaml
new file mode 100644
index 00000000000..5cab33ed672
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.in.yaml
@@ -0,0 +1,111 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /foo1
+ backendRefs:
+ - name: service-1
+ port: 8080
+ - matches:
+ - path:
+ value: /foo2
+ backendRefs:
+ - name: service-2
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /bar
+ backendRefs:
+ - name: service-3
+ port: 8080
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: 'primary.foo.com'
+ port: 3000
+referenceGrants:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: ReferenceGrant
+ metadata:
+ namespace: envoy-gateway
+ name: referencegrant-1
+ spec:
+ from:
+ - group: gateway.envoyproxy.io
+ kind: SecurityPolicy
+ namespace: default
+ to:
+ - group: ""
+ kind: Service
+securityPolicies:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route-1
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ extAuth:
+ failOpen: true
+ recomputeRoute: true
+ headersToExtAuth:
+ - header1
+ - header2
+ grpc:
+ backendRefs:
+ - name: service-2
+ kind: Service
+ port: 8080
+ - name: backend-fqdn
+ kind: Backend
+ group: gateway.envoyproxy.io
+ port: 3000
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml
new file mode 100644
index 00000000000..350fc8e908b
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml
@@ -0,0 +1,332 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo1
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ matches:
+ - path:
+ value: /foo2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-3
+ port: 8080
+ matches:
+ - path:
+ value: /bar
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+infraIR:
+ default/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-1
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route-1
+ namespace: default
+ spec:
+ extAuth:
+ failOpen: true
+ grpc:
+ backendRefs:
+ - kind: Service
+ name: service-2
+ port: 8080
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ port: 3000
+ headersToExtAuth:
+ - header1
+ - header2
+ recomputeRoute: true
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+xdsIR:
+ default/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo1
+ security:
+ extAuth:
+ failOpen: true
+ grpc:
+ authority: service-2.default:8080
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/extauth/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ name: securitypolicy/default/policy-for-http-route-1
+ recomputeRoute: true
+ - destination:
+ name: httproute/default/httproute-1/rule/1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo2
+ security:
+ extAuth:
+ failOpen: true
+ grpc:
+ authority: service-2.default:8080
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/extauth/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ name: securitypolicy/default/policy-for-http-route-1
+ recomputeRoute: true
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml
index d2aee51b27e..abd7ed641b9 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml
@@ -160,7 +160,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "80"
+ sectionName: http
validation:
caCertificateRefs:
- name: ca-cmap
@@ -177,7 +177,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: grpc-backend
- sectionName: "9000"
+ sectionName: grpc
validation:
caCertificateRefs:
- name: ca-cmap
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml
index a878d1aac62..c4f0d3b6c99 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml
@@ -10,7 +10,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: http-backend
- sectionName: "80"
+ sectionName: http
validation:
caCertificateRefs:
- group: ""
@@ -42,7 +42,7 @@ backendTLSPolicies:
- group: ""
kind: Service
name: grpc-backend
- sectionName: "9000"
+ sectionName: grpc
validation:
caCertificateRefs:
- group: ""
@@ -322,7 +322,7 @@ xdsIR:
grpc:
authority: grpc-backend.default:9000
destination:
- name: securitypolicy/default/policy-for-http-route/default/grpc-backend
+ name: securitypolicy/default/policy-for-http-route/extauth/0
settings:
- addressType: IP
endpoints:
@@ -330,6 +330,7 @@ xdsIR:
port: 9000
protocol: GRPC
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls-grpc/default-ca
@@ -365,7 +366,7 @@ xdsIR:
http:
authority: http-backend.envoy-gateway:80
destination:
- name: securitypolicy/default/policy-for-gateway/envoy-gateway/http-backend
+ name: securitypolicy/default/policy-for-gateway/extauth/0
settings:
- addressType: IP
endpoints:
@@ -373,6 +374,7 @@ xdsIR:
port: 80
protocol: HTTP
tls:
+ alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls-http/envoy-gateway-ca
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml
index f8395d24137..d72cd182896 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml
@@ -263,7 +263,7 @@ xdsIR:
grpc:
authority: grpc-backend.default:9000
destination:
- name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ name: securitypolicy/default/policy-for-http-route-1/extauth/0
settings:
- addressType: IP
endpoints:
@@ -301,7 +301,7 @@ xdsIR:
grpc:
authority: grpc-backend.default:9000
destination:
- name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ name: securitypolicy/default/policy-for-http-route-1/extauth/0
settings:
- addressType: IP
endpoints:
@@ -339,7 +339,7 @@ xdsIR:
http:
authority: http-backend.envoy-gateway:80
destination:
- name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ name: securitypolicy/default/policy-for-gateway-1/extauth/0
settings:
- addressType: IP
endpoints:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendcluster.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendcluster.in.yaml
new file mode 100644
index 00000000000..67b051e4b31
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendcluster.in.yaml
@@ -0,0 +1,101 @@
+secrets:
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ namespace: envoy-gateway
+ name: client1-secret
+ data:
+ client-secret: Y2xpZW50MTpzZWNyZXQK
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ namespace: envoy-gateway-system
+ name: envoy-oidc-hmac
+ data:
+ hmac-secret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY=
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.example.com
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/foo"
+ backendRefs:
+ - name: service-1
+ port: 8080
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: 'oauth.foo.com'
+ port: 443
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: policy-for-gateway
+ uid: b8284d0f-de82-4c65-b204-96a0d3f258a1
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ oidc:
+ provider:
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ port: 443
+ backendSettings:
+ retry:
+ numRetries: 3
+ perRetry:
+ backOff:
+ baseInterval: 1s
+ maxInterval: 5s
+ retryOn:
+ triggers: ["5xx", "gateway-error", "reset"]
+ issuer: "https://oauth.foo.com"
+ authorizationEndpoint: "https://oauth.foo.com/oauth2/v2/auth"
+ tokenEndpoint: "https://oauth.foo.com/token"
+ clientID: "client1.apps.googleusercontent.com"
+ clientSecret:
+ name: "client1-secret"
+ redirectURL: "https://www.example.com/bar/oauth2/callback"
+ logoutPath: "/bar/logout"
+ forwardAccessToken: true
+ defaultTokenTTL: 30m
+ refreshToken: true
+ defaultRefreshTokenTTL: 24h
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendcluster.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendcluster.out.yaml
new file mode 100644
index 00000000000..d878bcdb505
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendcluster.out.yaml
@@ -0,0 +1,256 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: oauth.foo.com
+ port: 443
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.example.com
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-gateway
+ namespace: envoy-gateway
+ uid: b8284d0f-de82-4c65-b204-96a0d3f258a1
+ spec:
+ oidc:
+ clientID: client1.apps.googleusercontent.com
+ clientSecret:
+ group: null
+ kind: null
+ name: client1-secret
+ defaultRefreshTokenTTL: 24h0m0s
+ defaultTokenTTL: 30m0s
+ forwardAccessToken: true
+ logoutPath: /bar/logout
+ provider:
+ authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ port: 443
+ backendSettings:
+ retry:
+ numRetries: 3
+ perRetry:
+ backOff:
+ baseInterval: 1s
+ maxInterval: 5s
+ retryOn:
+ triggers:
+ - 5xx
+ - gateway-error
+ - reset
+ issuer: https://oauth.foo.com
+ tokenEndpoint: https://oauth.foo.com/token
+ redirectURL: https://www.example.com/bar/oauth2/callback
+ refreshToken: true
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ security:
+ oidc:
+ clientID: client1.apps.googleusercontent.com
+ clientSecret: '[redacted]'
+ cookieSuffix: b0a1b740
+ defaultRefreshTokenTTL: 24h0m0s
+ defaultTokenTTL: 30m0s
+ forwardAccessToken: true
+ hmacSecret: '[redacted]'
+ logoutPath: /bar/logout
+ name: securitypolicy/envoy-gateway/policy-for-gateway
+ provider:
+ authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth
+ destination:
+ name: securitypolicy/envoy-gateway/policy-for-gateway/oidc/0
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: oauth.foo.com
+ port: 443
+ protocol: HTTPS
+ weight: 1
+ tokenEndpoint: https://oauth.foo.com/token
+ traffic:
+ retry:
+ numRetries: 3
+ perRetry:
+ backOff:
+ baseInterval: 1s
+ maxInterval: 5s
+ retryOn:
+ triggers:
+ - 5xx
+ - gateway-error
+ - reset
+ redirectPath: /bar/oauth2/callback
+ redirectURL: https://www.example.com/bar/oauth2/callback
+ refreshToken: true
+ scopes:
+ - openid
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies.out.yaml
index 2482d1bc05b..a42e482a758 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies.out.yaml
@@ -178,12 +178,12 @@ xdsIR:
security:
oidc:
clientID: client1.apps.googleusercontent.com
- clientSecret: Y2xpZW50MTpzZWNyZXQK
+ clientSecret: '[redacted]'
cookieNameOverrides:
accessToken: CustomAccessTokenCookie
idToken: CustomIdTokenCookie
cookieSuffix: b0a1b740
- hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY=
+ hmacSecret: '[redacted]'
logoutPath: /bar/logout
name: securitypolicy/envoy-gateway/policy-for-gateway
provider:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml
index d97cf0469df..b5031e6aa50 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml
@@ -132,3 +132,4 @@ securityPolicies:
defaultTokenTTL: 1h
refreshToken: true
defaultRefreshTokenTTL: 48h
+ cookieDomain: "example.com"
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml
index 9d27209dbe3..1d9093a8d38 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml
@@ -147,6 +147,7 @@ securityPolicies:
group: null
kind: null
name: client2-secret
+ cookieDomain: example.com
defaultRefreshTokenTTL: 48h0m0s
defaultTokenTTL: 1h0m0s
forwardAccessToken: true
@@ -272,12 +273,13 @@ xdsIR:
security:
oidc:
clientID: client2.oauth.foo.com
- clientSecret: Y2xpZW50MTpzZWNyZXQK
+ clientSecret: '[redacted]'
+ cookieDomain: example.com
cookieSuffix: 5f93c2e4
defaultRefreshTokenTTL: 48h0m0s
defaultTokenTTL: 1h0m0s
forwardAccessToken: true
- hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY=
+ hmacSecret: '[redacted]'
logoutPath: /foo/logout
name: securitypolicy/default/policy-for-http-route
provider:
@@ -315,12 +317,12 @@ xdsIR:
security:
oidc:
clientID: client1.apps.googleusercontent.com
- clientSecret: Y2xpZW50MTpzZWNyZXQK
+ clientSecret: '[redacted]'
cookieSuffix: b0a1b740
defaultRefreshTokenTTL: 24h0m0s
defaultTokenTTL: 30m0s
forwardAccessToken: true
- hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY=
+ hmacSecret: '[redacted]'
logoutPath: /bar/logout
name: securitypolicy/envoy-gateway/policy-for-gateway
provider:
diff --git a/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml b/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml
index 52e3a0563e9..d3a6e8bdc19 100644
--- a/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml
+++ b/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml
@@ -182,14 +182,16 @@ xdsIR:
name: tcproute/default/tcproute-1
tls:
terminate:
+ alpnProtocols: []
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls:
+ alpnProtocols: []
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
- address: 0.0.0.0
name: envoy-gateway/gateway-1/tls-hostname
@@ -210,12 +212,14 @@ xdsIR:
snis:
- foo.bar.com
terminate:
+ alpnProtocols: []
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls:
+ alpnProtocols: []
certificates:
- name: envoy-gateway/tls-secret-1
- privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+ privateKey: '[redacted]'
serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
diff --git a/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml b/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml
index c82e53e39e0..951d4c7529c 100644
--- a/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml
+++ b/internal/gatewayapi/testdata/tcproute-with-backend.out.yaml
@@ -16,7 +16,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -92,9 +92,10 @@ tcpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: Route is accepted
- reason: Accepted
- status: "True"
+ message: 'backend reference validation failed: backend is not supported for
+ route kind: TCPRoute'
+ reason: Failed to process the settings associated with the TCP route.
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: Resource default/backend-ip of type Backend is not supported for
@@ -115,9 +116,3 @@ xdsIR:
- address: 0.0.0.0
name: envoy-gateway/gateway-1/tcp
port: 10090
- routes:
- - destination:
- name: tcproute/default/tcproute-1/rule/-1
- settings:
- - weight: 1
- name: tcproute/default/tcproute-1
diff --git a/internal/gatewayapi/testdata/tlsroute-invalid-reference-grant.in.yaml b/internal/gatewayapi/testdata/tlsroute-invalid-reference-grant.in.yaml
new file mode 100644
index 00000000000..99d36258032
--- /dev/null
+++ b/internal/gatewayapi/testdata/tlsroute-invalid-reference-grant.in.yaml
@@ -0,0 +1,139 @@
+referenceGrants:
+ - apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: ReferenceGrant
+ metadata:
+ name: reference-grant-wrong-namespace
+ namespace: gateway-conformance-infra
+ spec:
+ from:
+ - group: gateway.networking.k8s.io
+ kind: TLSRoute
+ namespace: gateway-conformance-infra
+ to:
+ - group: ""
+ kind: Service
+ name: tls-backend
+
+ - apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: ReferenceGrant
+ metadata:
+ name: reference-grant-wrong-from-group
+ namespace: gateway-conformance-app-backend
+ spec:
+ from:
+ - group: not-the-group-youre-looking-for
+ kind: TLSRoute
+ namespace: gateway-conformance-infra
+ to:
+ - group: ""
+ kind: Service
+ name: tls-backend
+ - apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: ReferenceGrant
+ metadata:
+ name: reference-grant-wrong-from-kind
+ namespace: gateway-conformance-app-backend
+ spec:
+ from:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ namespace: gateway-conformance-infra
+ to:
+ - group: ""
+ kind: Service
+ name: tls-backend
+ - apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: ReferenceGrant
+ metadata:
+ name: reference-grant-wrong-from-namespace
+ namespace: gateway-conformance-app-backend
+ spec:
+ from:
+ - group: gateway.networking.k8s.io
+ kind: TLSRoute
+ namespace: not-the-namespace-youre-looking-for
+ to:
+ - group: ""
+ kind: Service
+ name: tls-backend
+
+ - apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: ReferenceGrant
+ metadata:
+ name: reference-grant-wrong-to-group
+ namespace: gateway-conformance-app-backend
+ spec:
+ from:
+ - group: gateway.networking.k8s.io
+ kind: TLSRoute
+ namespace: gateway-conformance-infra
+ to:
+ - group: not-the-group-youre-looking-for
+ kind: Service
+ name: tls-backend
+
+ - apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: ReferenceGrant
+ metadata:
+ name: reference-grant-wrong-to-kind
+ namespace: gateway-conformance-app-backend
+ spec:
+ from:
+ - group: gateway.networking.k8s.io
+ kind: TLSRoute
+ namespace: gateway-conformance-infra
+ to:
+ - group: ""
+ kind: Secret
+ name: tls-backend
+
+ - apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: ReferenceGrant
+ metadata:
+ name: reference-grant-wrong-to-name
+ namespace: gateway-conformance-app-backend
+ spec:
+ from:
+ - group: gateway.networking.k8s.io
+ kind: TLSRoute
+ namespace: gateway-conformance-infra
+ to:
+ - group: ""
+ kind: Service
+ name: not-the-service-youre-looking-for
+tlsRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: TLSRoute
+ metadata:
+ name: gateway-conformance-infra-test
+ namespace: gateway-conformance-infra
+ spec:
+ parentRefs:
+ - name: gateway-tlsroute-referencegrant
+ hostnames:
+ - abc.example.com
+ rules:
+ - backendRefs:
+ - name: tls-backend
+ namespace: gateway-conformance-app-backend
+ port: 443
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: Gateway
+ metadata:
+ name: gateway-tlsroute-referencegrant
+ namespace: gateway-conformance-infra
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: https
+ port: 443
+ protocol: TLS
+ hostname: "*.example.com"
+ allowedRoutes:
+ namespaces:
+ from: Same
+ kinds:
+ - kind: TLSRoute
+ tls:
+ mode: Passthrough
diff --git a/internal/gatewayapi/testdata/tlsroute-invalid-reference-grant.out.yaml b/internal/gatewayapi/testdata/tlsroute-invalid-reference-grant.out.yaml
new file mode 100644
index 00000000000..833bcd48919
--- /dev/null
+++ b/internal/gatewayapi/testdata/tlsroute-invalid-reference-grant.out.yaml
@@ -0,0 +1,102 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-tlsroute-referencegrant
+ namespace: gateway-conformance-infra
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ kinds:
+ - kind: TLSRoute
+ namespaces:
+ from: Same
+ hostname: '*.example.com'
+ name: https
+ port: 443
+ protocol: TLS
+ tls:
+ mode: Passthrough
+ status:
+ listeners:
+ - attachedRoutes: 0
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: https
+ supportedKinds:
+ - kind: TLSRoute
+infraIR:
+ gateway-conformance-infra/gateway-tlsroute-referencegrant:
+ proxy:
+ listeners:
+ - address: null
+ name: gateway-conformance-infra/gateway-tlsroute-referencegrant/https
+ ports:
+ - containerPort: 10443
+ name: tls-443
+ protocol: TLS
+ servicePort: 443
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-tlsroute-referencegrant
+ gateway.envoyproxy.io/owning-gateway-namespace: gateway-conformance-infra
+ name: gateway-conformance-infra/gateway-tlsroute-referencegrant
+tlsRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: TLSRoute
+ metadata:
+ creationTimestamp: null
+ name: gateway-conformance-infra-test
+ namespace: gateway-conformance-infra
+ spec:
+ hostnames:
+ - abc.example.com
+ parentRefs:
+ - name: gateway-tlsroute-referencegrant
+ rules:
+ - backendRefs:
+ - name: tls-backend
+ namespace: gateway-conformance-app-backend
+ port: 443
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: No listeners included by this parent ref allowed this attachment.
+ reason: NotAllowedByListeners
+ status: "False"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Backend ref to Service gateway-conformance-app-backend/tls-backend
+ not permitted by any ReferenceGrant.
+ reason: RefNotPermitted
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-tlsroute-referencegrant
+xdsIR:
+ gateway-conformance-infra/gateway-tlsroute-referencegrant:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ tcp:
+ - address: 0.0.0.0
+ name: gateway-conformance-infra/gateway-tlsroute-referencegrant/https
+ port: 10443
diff --git a/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml b/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml
index f5839c370d4..97bce6d0acf 100644
--- a/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml
+++ b/internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml
@@ -16,7 +16,7 @@ backends:
message: The Backend was accepted
reason: Accepted
status: "True"
- type: Invalid
+ type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
@@ -100,10 +100,9 @@ tlsRoutes:
status: "True"
type: Accepted
- lastTransitionTime: null
- message: Resource default/backend-ip of type Backend is not supported for
- TLSRoute routes
- reason: UnsupportedValue
- status: "False"
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
@@ -122,7 +121,11 @@ xdsIR:
- destination:
name: tlsroute/default/tlsroute-1/rule/-1
settings:
- - weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ weight: 1
name: tlsroute/default/tlsroute-1
tls:
inspector:
diff --git a/internal/gatewayapi/tls.go b/internal/gatewayapi/tls.go
index 1d38897ed26..acde9bed339 100644
--- a/internal/gatewayapi/tls.go
+++ b/internal/gatewayapi/tls.go
@@ -88,10 +88,13 @@ func validateTLSSecretsData(secrets []*corev1.Secret, host *gwapiv1.Hostname) er
func verifyHostname(cert *x509.Certificate, host *gwapiv1.Hostname) ([]string, error) {
var matchedHosts []string
+ listenerContext := ListenerContext{
+ Listener: &gwapiv1.Listener{Hostname: host},
+ }
if len(cert.DNSNames) > 0 {
- matchedHosts = computeHosts(cert.DNSNames, host)
+ matchedHosts = computeHosts(cert.DNSNames, &listenerContext)
} else {
- matchedHosts = computeHosts([]string{cert.Subject.CommonName}, host)
+ matchedHosts = computeHosts([]string{cert.Subject.CommonName}, &listenerContext)
}
if len(matchedHosts) > 0 {
diff --git a/internal/gatewayapi/tls_test.go b/internal/gatewayapi/tls_test.go
index d97824382ce..87e8b27cad6 100644
--- a/internal/gatewayapi/tls_test.go
+++ b/internal/gatewayapi/tls_test.go
@@ -159,7 +159,6 @@ func TestValidateTLSSecretsData(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.Name, func(t *testing.T) {
secrets := createTestSecrets(t, tc.CertFile, tc.KeyFile)
require.NotNil(t, secrets)
@@ -204,7 +203,6 @@ func TestValidateCertificate(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.Name, func(t *testing.T) {
certData, err := os.ReadFile(filepath.Join("testdata", "tls", tc.CertFile))
require.NoError(t, err)
diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go
index 1be3f59f229..23e651b6c69 100644
--- a/internal/gatewayapi/translator.go
+++ b/internal/gatewayapi/translator.go
@@ -16,31 +16,12 @@ import (
gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/wasm"
)
const (
- KindConfigMap = "ConfigMap"
- KindClientTrafficPolicy = "ClientTrafficPolicy"
- KindBackendTrafficPolicy = "BackendTrafficPolicy"
- KindBackendTLSPolicy = "BackendTLSPolicy"
- KindEnvoyPatchPolicy = "EnvoyPatchPolicy"
- KindEnvoyExtensionPolicy = "EnvoyExtensionPolicy"
- KindSecurityPolicy = "SecurityPolicy"
- KindEnvoyProxy = "EnvoyProxy"
- KindGateway = "Gateway"
- KindGatewayClass = "GatewayClass"
- KindGRPCRoute = "GRPCRoute"
- KindHTTPRoute = "HTTPRoute"
- KindNamespace = "Namespace"
- KindTLSRoute = "TLSRoute"
- KindTCPRoute = "TCPRoute"
- KindUDPRoute = "UDPRoute"
- KindService = "Service"
- KindServiceImport = "ServiceImport"
- KindSecret = "Secret"
-
GroupMultiClusterService = "multicluster.x-k8s.io"
// OwningGatewayNamespaceLabel is the owner reference label used for managed infra.
// The value should be the namespace of the accepted Envoy Gateway.
@@ -61,8 +42,8 @@ const (
var _ TranslatorManager = (*Translator)(nil)
type TranslatorManager interface {
- Translate(resources *Resources) (*TranslateResult, error)
- GetRelevantGateways(resources *Resources) []*GatewayContext
+ Translate(resources *resource.Resources) (*TranslateResult, error)
+ GetRelevantGateways(resources *resource.Resources) []*GatewayContext
RoutesTranslator
ListenersTranslator
@@ -113,9 +94,9 @@ type Translator struct {
}
type TranslateResult struct {
- Resources
- XdsIR XdsIRMap `json:"xdsIR" yaml:"xdsIR"`
- InfraIR InfraIRMap `json:"infraIR" yaml:"infraIR"`
+ resource.Resources
+ XdsIR resource.XdsIRMap `json:"xdsIR" yaml:"xdsIR"`
+ InfraIR resource.InfraIRMap `json:"infraIR" yaml:"infraIR"`
}
func newTranslateResult(gateways []*GatewayContext,
@@ -131,7 +112,7 @@ func newTranslateResult(gateways []*GatewayContext,
envoyExtensionPolicies []*egv1a1.EnvoyExtensionPolicy,
extPolicies []unstructured.Unstructured,
backends []*egv1a1.Backend,
- xdsIR XdsIRMap, infraIR InfraIRMap,
+ xdsIR resource.XdsIRMap, infraIR resource.InfraIRMap,
) *TranslateResult {
translateResult := &TranslateResult{
XdsIR: xdsIR,
@@ -168,7 +149,7 @@ func newTranslateResult(gateways []*GatewayContext,
return translateResult
}
-func (t *Translator) Translate(resources *Resources) (*TranslateResult, error) {
+func (t *Translator) Translate(resources *resource.Resources) (*TranslateResult, error) {
// Get Gateways belonging to our GatewayClass.
gateways := t.GetRelevantGateways(resources)
@@ -178,7 +159,7 @@ func (t *Translator) Translate(resources *Resources) (*TranslateResult, error) {
})
// Build IR maps.
- xdsIR, infraIR := t.InitIRs(gateways, resources)
+ xdsIR, infraIR := t.InitIRs(gateways)
// Process all Listeners for all relevant Gateways.
t.ProcessListeners(gateways, xdsIR, infraIR, resources)
@@ -186,11 +167,8 @@ func (t *Translator) Translate(resources *Resources) (*TranslateResult, error) {
// Process EnvoyPatchPolicies
t.ProcessEnvoyPatchPolicies(resources.EnvoyPatchPolicies, xdsIR)
- // Process ClientTrafficPolicies
- clientTrafficPolicies := t.ProcessClientTrafficPolicies(resources, gateways, xdsIR, infraIR)
-
// Process all Addresses for all relevant Gateways.
- t.ProcessAddresses(gateways, xdsIR, infraIR, resources)
+ t.ProcessAddresses(gateways, xdsIR, infraIR)
// process all Backends
backends := t.ProcessBackends(resources.Backends)
@@ -210,6 +188,9 @@ func (t *Translator) Translate(resources *Resources) (*TranslateResult, error) {
// Process all relevant UDPRoutes.
udpRoutes := t.ProcessUDPRoutes(resources.UDPRoutes, gateways, resources, xdsIR)
+ // Process ClientTrafficPolicies
+ clientTrafficPolicies := t.ProcessClientTrafficPolicies(resources, gateways, xdsIR, infraIR)
+
// Process BackendTrafficPolicies
routes := []RouteContext{}
for _, h := range httpRoutes {
@@ -230,7 +211,7 @@ func (t *Translator) Translate(resources *Resources) (*TranslateResult, error) {
// Process BackendTrafficPolicies
backendTrafficPolicies := t.ProcessBackendTrafficPolicies(
- resources.BackendTrafficPolicies, gateways, routes, xdsIR)
+ resources, gateways, routes, xdsIR)
// Process SecurityPolicies
securityPolicies := t.ProcessSecurityPolicies(
@@ -263,7 +244,7 @@ func (t *Translator) Translate(resources *Resources) (*TranslateResult, error) {
// GetRelevantGateways returns GatewayContexts, containing a copy of the original
// Gateway with the Listener statuses reset.
-func (t *Translator) GetRelevantGateways(resources *Resources) []*GatewayContext {
+func (t *Translator) GetRelevantGateways(resources *resource.Resources) []*GatewayContext {
var relevant []*GatewayContext
for _, gateway := range resources.Gateways {
@@ -285,9 +266,9 @@ func (t *Translator) GetRelevantGateways(resources *Resources) []*GatewayContext
}
// InitIRs checks if mergeGateways is enabled in EnvoyProxy config and initializes XdsIR and InfraIR maps with adequate keys.
-func (t *Translator) InitIRs(gateways []*GatewayContext, resources *Resources) (map[string]*ir.Xds, map[string]*ir.Infra) {
- xdsIR := make(XdsIRMap)
- infraIR := make(InfraIRMap)
+func (t *Translator) InitIRs(gateways []*GatewayContext) (map[string]*ir.Xds, map[string]*ir.Infra) {
+ xdsIR := make(resource.XdsIRMap)
+ infraIR := make(resource.InfraIRMap)
var irKey string
for _, gateway := range gateways {
diff --git a/internal/gatewayapi/translator_test.go b/internal/gatewayapi/translator_test.go
index 357f6586bee..96a88bfdec9 100644
--- a/internal/gatewayapi/translator_test.go
+++ b/internal/gatewayapi/translator_test.go
@@ -14,6 +14,7 @@ import (
"fmt"
"os"
"path/filepath"
+ "reflect"
"strconv"
"strings"
"testing"
@@ -33,6 +34,8 @@ import (
"sigs.k8s.io/yaml"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
+ "github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils/field"
"github.com/envoyproxy/gateway/internal/utils/file"
"github.com/envoyproxy/gateway/internal/wasm"
@@ -64,12 +67,11 @@ func TestTranslate(t *testing.T) {
require.NoError(t, err)
for _, inputFile := range inputFiles {
- inputFile := inputFile
t.Run(testName(inputFile), func(t *testing.T) {
input, err := os.ReadFile(inputFile)
require.NoError(t, err)
- resources := &Resources{}
+ resources := &resource.Resources{}
mustUnmarshal(t, input, resources)
envoyPatchPolicyEnabled := true
backendEnabled := true
@@ -318,9 +320,11 @@ func TestTranslate(t *testing.T) {
opts := []cmp.Option{
cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"),
+ cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"),
+ cmp.Transformer("ClearXdsEqual", xdsWithoutEqual),
+ cmpopts.IgnoreTypes(ir.PrivateBytes{}),
cmpopts.EquateEmpty(),
}
-
require.Empty(t, cmp.Diff(want, got, opts...))
})
}
@@ -331,12 +335,11 @@ func TestTranslateWithExtensionKinds(t *testing.T) {
require.NoError(t, err)
for _, inputFile := range inputFiles {
- inputFile := inputFile
t.Run(testName(inputFile), func(t *testing.T) {
input, err := os.ReadFile(inputFile)
require.NoError(t, err)
- resources := &Resources{}
+ resources := &resource.Resources{}
mustUnmarshal(t, input, resources)
translator := &Translator{
@@ -516,8 +519,11 @@ func TestTranslateWithExtensionKinds(t *testing.T) {
want := &TranslateResult{}
mustUnmarshal(t, output, want)
- opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime")
- require.Empty(t, cmp.Diff(want, got, opts))
+ opts := []cmp.Option{
+ cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"),
+ cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"),
+ }
+ require.Empty(t, cmp.Diff(want, got, opts...))
})
}
}
@@ -625,7 +631,6 @@ func TestIsValidHostname(t *testing.T) {
}
for _, tc := range testcases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := translator.validateHostname(tc.hostname)
if tc.err == "" {
@@ -745,7 +750,6 @@ func TestIsValidCrossNamespaceRef(t *testing.T) {
testcases = append(testcases, modified)
for _, tc := range testcases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var referenceGrants []*gwapiv1b1.ReferenceGrant
if tc.referenceGrant != nil {
@@ -836,7 +840,7 @@ type mockWasmCache struct{}
func (m *mockWasmCache) Start(_ context.Context) {}
-func (m *mockWasmCache) Get(downloadURL string, _ wasm.GetOptions) (url string, checksum string, err error) {
+func (m *mockWasmCache) Get(downloadURL string, options wasm.GetOptions) (url string, checksum string, err error) {
// This is a mock implementation of the wasm.Cache.Get method.
sha := sha256.Sum256([]byte(downloadURL))
hashedName := hex.EncodeToString(sha[:])
@@ -844,7 +848,49 @@ func (m *mockWasmCache) Get(downloadURL string, _ wasm.GetOptions) (url string,
salt = append(salt, hashedName...)
sha = sha256.Sum256(salt)
checksum = hex.EncodeToString(sha[:])
+ if options.Checksum != "" && checksum != options.Checksum {
+ return "", "", fmt.Errorf("module downloaded from %v has checksum %v, which does not match: %v", downloadURL, checksum, options.Checksum)
+ }
return fmt.Sprintf("https://envoy-gateway:18002/%s.wasm", hashedName), checksum, nil
}
func (m *mockWasmCache) Cleanup() {}
+
+// ir.Xds implements a custom Equal method which ensures exact equality, even
+// over redacted fields. This function is used to remove the Equal method from
+// the type, but ensure that the set of fields is the same.
+// This allows us to use cmp.Diff to compare the types with field-level cmpopts.
+func xdsWithoutEqual(a *ir.Xds) any {
+ ret := struct {
+ AccessLog *ir.AccessLog
+ Tracing *ir.Tracing
+ Metrics *ir.Metrics
+ HTTP []*ir.HTTPListener
+ TCP []*ir.TCPListener
+ UDP []*ir.UDPListener
+ EnvoyPatchPolicies []*ir.EnvoyPatchPolicy
+ FilterOrder []egv1a1.FilterPosition
+ }{
+ AccessLog: a.AccessLog,
+ Tracing: a.Tracing,
+ Metrics: a.Metrics,
+ HTTP: a.HTTP,
+ TCP: a.TCP,
+ UDP: a.UDP,
+ EnvoyPatchPolicies: a.EnvoyPatchPolicies,
+ FilterOrder: a.FilterOrder,
+ }
+
+ // Ensure we didn't drop an exported field.
+ ta, tr := reflect.TypeOf(*a), reflect.TypeOf(ret)
+ for i := 0; i < ta.NumField(); i++ {
+ aField := ta.Field(i)
+ if rField, ok := tr.FieldByName(aField.Name); !ok || aField.Type != rField.Type {
+ // We panic here because this is test code, and it would be hard to
+ // plumb the error out.
+ panic(fmt.Sprintf("field %q is missing or has wrong type in the ir.Xds mirror", aField.Name))
+ }
+ }
+
+ return ret
+}
diff --git a/internal/gatewayapi/validate.go b/internal/gatewayapi/validate.go
index 5c442812d8b..37a007444e2 100644
--- a/internal/gatewayapi/validate.go
+++ b/internal/gatewayapi/validate.go
@@ -20,36 +20,39 @@ import (
gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
)
func (t *Translator) validateBackendRef(backendRefContext BackendRefContext, parentRef *RouteParentContext, route RouteContext,
- resources *Resources, backendNamespace string, routeKind gwapiv1.Kind,
-) bool {
+ resources *resource.Resources, backendNamespace string, routeKind gwapiv1.Kind,
+) error {
backendRef := GetBackendRef(backendRefContext)
- if !t.validateBackendRefFilters(backendRefContext, parentRef, route, routeKind) {
- return false
+ if err := t.validateBackendRefFilters(backendRefContext, parentRef, route, routeKind); err != nil {
+ return fmt.Errorf("error validating backend filters: %w", err)
}
- if !t.validateBackendRefGroup(backendRef, parentRef, route) {
- return false
+ if err := t.validateBackendRefGroup(backendRef, parentRef, route); err != nil {
+ return fmt.Errorf("error validating backend group: %w", err)
}
- if !t.validateBackendRefKind(backendRef, parentRef, route) {
- return false
+ if err := t.validateBackendRefKind(backendRef, parentRef, route); err != nil {
+ return fmt.Errorf("error validating backend kind: %w", err)
}
- if !t.validateBackendNamespace(backendRef, parentRef, route, resources, routeKind) {
- return false
+ if err := t.validateBackendNamespace(backendRef, parentRef, route, resources, routeKind); err != nil {
+ return fmt.Errorf("error validating backend namespace: %w", err)
}
- if !t.validateBackendPort(backendRef, parentRef, route) {
- return false
+ if err := t.validateBackendPort(backendRef, parentRef, route); err != nil {
+ return fmt.Errorf("error validating backend port: %w", err)
}
+
protocol := corev1.ProtocolTCP
- if routeKind == KindUDPRoute {
+ if routeKind == resource.KindUDPRoute {
protocol = corev1.ProtocolUDP
}
- backendRefKind := KindDerefOr(backendRef.Kind, KindService)
+
+ backendRefKind := KindDerefOr(backendRef.Kind, resource.KindService)
switch backendRefKind {
- case KindService:
+ case resource.KindService:
if err := validateBackendService(backendRef.BackendObjectReference, resources, backendNamespace, protocol); err != nil {
routeStatus := GetRouteStatus(route)
status.SetRouteStatusCondition(routeStatus,
@@ -60,21 +63,21 @@ func (t *Translator) validateBackendRef(backendRefContext BackendRefContext, par
gwapiv1.RouteReasonBackendNotFound,
err.Error(),
)
- return false
+ return fmt.Errorf("backend service validation failed: %w", err)
}
- case KindServiceImport:
- if !t.validateBackendServiceImport(backendRef, parentRef, resources, backendNamespace, route, protocol) {
- return false
+ case resource.KindServiceImport:
+ if err := t.validateBackendServiceImport(backendRef, parentRef, resources, backendNamespace, route, protocol); err != nil {
+ return fmt.Errorf("backend service import validation failed: %w", err)
}
case egv1a1.KindBackend:
- if !t.validateBackendRefBackend(backendRef, parentRef, resources, backendNamespace, route, routeKind) {
- return false
+ if err := t.validateBackendRefBackend(backendRef, parentRef, resources, backendNamespace, route, routeKind); err != nil {
+ return fmt.Errorf("backend reference validation failed: %w", err)
}
}
- return true
+ return nil
}
-func (t *Translator) validateBackendRefGroup(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) bool {
+func (t *Translator) validateBackendRefGroup(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) error {
if backendRef.Group != nil && *backendRef.Group != "" && *backendRef.Group != GroupMultiClusterService && *backendRef.Group != egv1a1.GroupName {
routeStatus := GetRouteStatus(route)
status.SetRouteStatusCondition(routeStatus,
@@ -85,13 +88,13 @@ func (t *Translator) validateBackendRefGroup(backendRef *gwapiv1a2.BackendRef, p
gwapiv1.RouteReasonInvalidKind,
fmt.Sprintf("Group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string), %s and %s are supported", GroupMultiClusterService, egv1a1.GroupName),
)
- return false
+ return fmt.Errorf("unsupported backend reference group: %s", *backendRef.Group)
}
- return true
+ return nil
}
-func (t *Translator) validateBackendRefKind(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) bool {
- if backendRef.Kind != nil && *backendRef.Kind != KindService && *backendRef.Kind != KindServiceImport && *backendRef.Kind != egv1a1.KindBackend {
+func (t *Translator) validateBackendRefKind(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) error {
+ if backendRef.Kind != nil && *backendRef.Kind != resource.KindService && *backendRef.Kind != resource.KindServiceImport && *backendRef.Kind != egv1a1.KindBackend {
routeStatus := GetRouteStatus(route)
status.SetRouteStatusCondition(routeStatus,
parentRef.routeParentStatusIdx,
@@ -101,30 +104,30 @@ func (t *Translator) validateBackendRefKind(backendRef *gwapiv1a2.BackendRef, pa
gwapiv1.RouteReasonInvalidKind,
"Kind is invalid, only Service, MCS ServiceImport and Envoy Gateway Backend are supported",
)
- return false
+ return fmt.Errorf("unsupported backend reference kind: %s", *backendRef.Kind)
}
- return true
+ return nil
}
-func (t *Translator) validateBackendRefFilters(backendRef BackendRefContext, parentRef *RouteParentContext, route RouteContext, routeKind gwapiv1.Kind) bool {
+func (t *Translator) validateBackendRefFilters(backendRef BackendRefContext, parentRef *RouteParentContext, route RouteContext, routeKind gwapiv1.Kind) error {
filters := GetFilters(backendRef)
var unsupportedFilters bool
switch routeKind {
- case KindHTTPRoute:
+ case resource.KindHTTPRoute:
for _, filter := range filters.([]gwapiv1.HTTPRouteFilter) {
if filter.Type != gwapiv1.HTTPRouteFilterRequestHeaderModifier && filter.Type != gwapiv1.HTTPRouteFilterResponseHeaderModifier {
unsupportedFilters = true
}
}
- case KindGRPCRoute:
+ case resource.KindGRPCRoute:
for _, filter := range filters.([]gwapiv1.GRPCRouteFilter) {
if filter.Type != gwapiv1.GRPCRouteFilterRequestHeaderModifier && filter.Type != gwapiv1.GRPCRouteFilterResponseHeaderModifier {
unsupportedFilters = true
}
}
default:
- return true
+ return nil
}
if unsupportedFilters {
@@ -137,15 +140,15 @@ func (t *Translator) validateBackendRefFilters(backendRef BackendRefContext, par
"UnsupportedRefValue",
"Specific filter is not supported within BackendRef, only RequestHeaderModifier and ResponseHeaderModifier are supported",
)
- return false
+ return errors.New("unsupported filter type in backend reference")
}
- return true
+ return nil
}
func (t *Translator) validateBackendNamespace(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext,
- resources *Resources, routeKind gwapiv1.Kind,
-) bool {
+ resources *resource.Resources, routeKind gwapiv1.Kind,
+) error {
if backendRef.Namespace != nil && string(*backendRef.Namespace) != "" && string(*backendRef.Namespace) != route.GetNamespace() {
if !t.validateCrossNamespaceRef(
crossNamespaceFrom{
@@ -155,7 +158,7 @@ func (t *Translator) validateBackendNamespace(backendRef *gwapiv1a2.BackendRef,
},
crossNamespaceTo{
group: GroupDerefOr(backendRef.Group, ""),
- kind: KindDerefOr(backendRef.Kind, KindService),
+ kind: KindDerefOr(backendRef.Kind, resource.KindService),
namespace: string(*backendRef.Namespace),
name: string(backendRef.Name),
},
@@ -168,18 +171,17 @@ func (t *Translator) validateBackendNamespace(backendRef *gwapiv1a2.BackendRef,
gwapiv1.RouteConditionResolvedRefs,
metav1.ConditionFalse,
gwapiv1.RouteReasonRefNotPermitted,
- fmt.Sprintf("Backend ref to %s %s/%s not permitted by any ReferenceGrant.", KindDerefOr(backendRef.Kind, KindService), *backendRef.Namespace, backendRef.Name),
+ fmt.Sprintf("Backend ref to %s %s/%s not permitted by any ReferenceGrant.", KindDerefOr(backendRef.Kind, resource.KindService), *backendRef.Namespace, backendRef.Name),
)
- return false
+ return fmt.Errorf("cross-namespace reference not permitted for backend: %s", backendRef.Name)
}
}
- return true
+ return nil
}
-func (t *Translator) validateBackendPort(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) bool {
- // Envoy Gateway Backends do not require a port in the backend ref
+func (t *Translator) validateBackendPort(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) error {
if backendRef != nil && backendRef.Kind != nil && string(*backendRef.Kind) == egv1a1.KindBackend {
- return true
+ return nil
}
if backendRef.Port == nil {
routeStatus := GetRouteStatus(route)
@@ -191,12 +193,12 @@ func (t *Translator) validateBackendPort(backendRef *gwapiv1a2.BackendRef, paren
"PortNotSpecified",
"A valid port number corresponding to a port on the Service must be specified",
)
- return false
+ return errors.New("port number not specified for backend reference")
}
- return true
+ return nil
}
-func validateBackendService(backendRef gwapiv1a2.BackendObjectReference, resources *Resources,
+func validateBackendService(backendRef gwapiv1a2.BackendObjectReference, resources *resource.Resources,
serviceNamespace string, protocol corev1.Protocol,
) error {
service := resources.GetService(serviceNamespace, string(backendRef.Name))
@@ -223,9 +225,9 @@ func validateBackendService(backendRef gwapiv1a2.BackendObjectReference, resourc
return nil
}
-func (t *Translator) validateBackendServiceImport(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, resources *Resources,
+func (t *Translator) validateBackendServiceImport(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, resources *resource.Resources,
serviceImportNamespace string, route RouteContext, protocol corev1.Protocol,
-) bool {
+) error {
serviceImport := resources.GetServiceImport(serviceImportNamespace, string(backendRef.Name))
if serviceImport == nil {
routeStatus := GetRouteStatus(route)
@@ -238,8 +240,9 @@ func (t *Translator) validateBackendServiceImport(backendRef *gwapiv1a2.BackendR
fmt.Sprintf("ServiceImport %s/%s not found", NamespaceDerefOr(backendRef.Namespace, route.GetNamespace()),
string(backendRef.Name)),
)
- return false
+ return fmt.Errorf("service import %s/%s not found", serviceImportNamespace, backendRef.Name)
}
+
var portFound bool
for _, port := range serviceImport.Spec.Ports {
portProtocol := port.Protocol
@@ -263,15 +266,15 @@ func (t *Translator) validateBackendServiceImport(backendRef *gwapiv1a2.BackendR
fmt.Sprintf(string(protocol)+" Port %d not found on ServiceImport %s/%s", *backendRef.Port, serviceImportNamespace,
string(backendRef.Name)),
)
- return false
+ return fmt.Errorf("%s port %d not found on service import %s/%s", string(protocol), *backendRef.Port, serviceImportNamespace, backendRef.Name)
}
- return true
+
+ return nil
}
-func (t *Translator) validateBackendRefBackend(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, resources *Resources,
+func (t *Translator) validateBackendRefBackend(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, resources *resource.Resources,
backendNamespace string, route RouteContext, kind gwapiv1.Kind,
-) bool {
- // TODO: support additional route kinds
+) error {
routeStatus := GetRouteStatus(route)
if !t.BackendEnabled {
@@ -284,10 +287,10 @@ func (t *Translator) validateBackendRefBackend(backendRef *gwapiv1a2.BackendRef,
fmt.Sprintf("Resource %s/%s of type Backend cannot be used since Backend is disabled in Envoy Gateway configuration",
NamespaceDerefOr(backendRef.Namespace, route.GetNamespace()), string(backendRef.Name)),
)
- return false
+ return errors.New("backend is disabled in Envoy Gateway configuration")
}
- if kind != KindHTTPRoute {
+ if kind != resource.KindHTTPRoute && kind != resource.KindTLSRoute {
status.SetRouteStatusCondition(routeStatus,
parentRef.routeParentStatusIdx,
route.GetGeneration(),
@@ -297,7 +300,7 @@ func (t *Translator) validateBackendRefBackend(backendRef *gwapiv1a2.BackendRef,
fmt.Sprintf("Resource %s/%s of type Backend is not supported for %s routes", NamespaceDerefOr(backendRef.Namespace, route.GetNamespace()),
string(backendRef.Name), kind),
)
- return false
+ return fmt.Errorf("backend is not supported for route kind: %s", kind)
}
backend := resources.GetBackend(backendNamespace, string(backendRef.Name))
@@ -311,7 +314,20 @@ func (t *Translator) validateBackendRefBackend(backendRef *gwapiv1a2.BackendRef,
fmt.Sprintf("Backend %s/%s not found", NamespaceDerefOr(backendRef.Namespace, route.GetNamespace()),
string(backendRef.Name)),
)
- return false
+ return fmt.Errorf("backend %s/%s not found", backendNamespace, backendRef.Name)
+ }
+
+ if err := validateBackend(backend); err != nil {
+ status.SetRouteStatusCondition(routeStatus,
+ parentRef.routeParentStatusIdx,
+ route.GetGeneration(),
+ gwapiv1.RouteConditionResolvedRefs,
+ metav1.ConditionFalse,
+ "UnsupportedRefAddressFound",
+ fmt.Sprintf("Invalid Backend reference to Backend %s/%s found", backendNamespace,
+ string(backendRef.Name)),
+ )
+ return fmt.Errorf("invalid backend reference: %w", err)
}
for _, bep := range backend.Spec.Endpoints {
@@ -325,11 +341,11 @@ func (t *Translator) validateBackendRefBackend(backendRef *gwapiv1a2.BackendRef,
fmt.Sprintf("Unix domain socket found in Backend %s/%s is not supported for xRoute backendRefs", backendNamespace,
string(backendRef.Name)),
)
- return false
+ return errors.New("unix domain sockets are not supported in backend references")
}
}
- return true
+ return nil
}
func (t *Translator) validateListenerConditions(listener *ListenerContext) (isReady bool) {
@@ -415,7 +431,7 @@ func (t *Translator) validateAllowedNamespaces(listener *ListenerContext) {
}
}
-func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerContext, resources *Resources) []*corev1.Secret {
+func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerContext, resources *resource.Resources) []*corev1.Secret {
if len(listener.TLS.CertificateRefs) == 0 {
status.SetGatewayListenerStatusCondition(listener.gateway.Gateway,
listener.listenerStatusIdx,
@@ -441,13 +457,13 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon
break
}
- if certificateRef.Kind != nil && string(*certificateRef.Kind) != KindSecret {
+ if certificateRef.Kind != nil && string(*certificateRef.Kind) != resource.KindSecret {
status.SetGatewayListenerStatusCondition(listener.gateway.Gateway,
listener.listenerStatusIdx,
gwapiv1.ListenerConditionResolvedRefs,
metav1.ConditionFalse,
gwapiv1.ListenerReasonInvalidCertificateRef,
- fmt.Sprintf("Listener's TLS certificate ref kind must be %s.", KindSecret),
+ fmt.Sprintf("Listener's TLS certificate ref kind must be %s.", resource.KindSecret),
)
break
}
@@ -458,12 +474,12 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon
if !t.validateCrossNamespaceRef(
crossNamespaceFrom{
group: gwapiv1.GroupName,
- kind: KindGateway,
+ kind: resource.KindGateway,
namespace: listener.gateway.Namespace,
},
crossNamespaceTo{
group: "",
- kind: KindSecret,
+ kind: resource.KindSecret,
namespace: string(*certificateRef.Namespace),
name: string(certificateRef.Name),
},
@@ -534,7 +550,7 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon
return secrets
}
-func (t *Translator) validateTLSConfiguration(listener *ListenerContext, resources *Resources) {
+func (t *Translator) validateTLSConfiguration(listener *ListenerContext, resources *resource.Resources) {
switch listener.Protocol {
case gwapiv1.HTTPProtocolType, gwapiv1.UDPProtocolType, gwapiv1.TCPProtocolType:
if listener.TLS != nil {
@@ -900,8 +916,8 @@ func (t *Translator) validateHostname(hostname string) error {
func (t *Translator) validateSecretRef(
allowCrossNamespace bool,
from crossNamespaceFrom,
- secretObjRef gwapiv1b1.SecretObjectReference,
- resources *Resources,
+ secretObjRef gwapiv1.SecretObjectReference,
+ resources *resource.Resources,
) (*corev1.Secret, error) {
if err := t.validateSecretObjectRef(allowCrossNamespace, from, secretObjRef, resources); err != nil {
return nil, err
@@ -924,8 +940,8 @@ func (t *Translator) validateSecretRef(
func (t *Translator) validateConfigMapRef(
allowCrossNamespace bool,
from crossNamespaceFrom,
- secretObjRef gwapiv1b1.SecretObjectReference,
- resources *Resources,
+ secretObjRef gwapiv1.SecretObjectReference,
+ resources *resource.Resources,
) (*corev1.ConfigMap, error) {
if err := t.validateSecretObjectRef(allowCrossNamespace, from, secretObjRef, resources); err != nil {
return nil, err
@@ -948,8 +964,8 @@ func (t *Translator) validateConfigMapRef(
func (t *Translator) validateSecretObjectRef(
allowCrossNamespace bool,
from crossNamespaceFrom,
- secretRef gwapiv1b1.SecretObjectReference,
- resources *Resources,
+ secretRef gwapiv1.SecretObjectReference,
+ resources *resource.Resources,
) error {
var kind string
if secretRef.Group != nil && string(*secretRef.Group) != "" {
@@ -957,13 +973,13 @@ func (t *Translator) validateSecretObjectRef(
}
if secretRef.Kind == nil { // nolint
- kind = KindSecret
- } else if string(*secretRef.Kind) == KindSecret {
- kind = KindSecret
- } else if string(*secretRef.Kind) == KindConfigMap {
- kind = KindConfigMap
+ kind = resource.KindSecret
+ } else if string(*secretRef.Kind) == resource.KindSecret {
+ kind = resource.KindSecret
+ } else if string(*secretRef.Kind) == resource.KindConfigMap {
+ kind = resource.KindConfigMap
} else {
- return fmt.Errorf("secret ref kind must be %s", KindSecret)
+ return fmt.Errorf("secret ref kind must be %s", resource.KindSecret)
}
if secretRef.Namespace != nil &&
@@ -1011,7 +1027,7 @@ func (t *Translator) validateExtServiceBackendReference(
backendRef *gwapiv1.BackendObjectReference,
ownerNamespace string,
policyKind string,
- resources *Resources,
+ resources *resource.Resources,
) error {
// These are sanity checks, they should never happen because the API server
// should have caught them
@@ -1021,7 +1037,7 @@ func (t *Translator) validateExtServiceBackendReference(
" the group field or setting it to an empty string) and the" +
" gateway.envoyproxy.io API group are supported")
}
- if backendRef.Kind != nil && *backendRef.Kind != KindService && *backendRef.Kind != egv1a1.KindBackend {
+ if backendRef.Kind != nil && *backendRef.Kind != resource.KindService && *backendRef.Kind != egv1a1.KindBackend {
return errors.New("kind is invalid, only Service (specified by omitting " +
"the kind field or setting it to 'Service') and Backend are supported")
}
@@ -1029,9 +1045,9 @@ func (t *Translator) validateExtServiceBackendReference(
return errors.New("a valid port number corresponding to a port on the Service must be specified")
}
- backendRefKind := KindDerefOr(backendRef.Kind, KindService)
+ backendRefKind := KindDerefOr(backendRef.Kind, resource.KindService)
switch backendRefKind {
- case KindService:
+ case resource.KindService:
// check if the service is valid
serviceNamespace := NamespaceDerefOr(backendRef.Namespace, ownerNamespace)
service := resources.GetService(serviceNamespace, string(backendRef.Name))
diff --git a/internal/globalratelimit/runner/runner.go b/internal/globalratelimit/runner/runner.go
index 0a2d987c182..e3430373454 100644
--- a/internal/globalratelimit/runner/runner.go
+++ b/internal/globalratelimit/runner/runner.go
@@ -7,13 +7,10 @@ package runner
import (
"context"
- "crypto/rand"
"crypto/tls"
- "crypto/x509"
"fmt"
"math"
"net"
- "os"
"strconv"
discoveryv3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
@@ -21,11 +18,11 @@ import (
cachev3 "github.com/envoyproxy/go-control-plane/pkg/cache/v3"
resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3"
serverv3 "github.com/envoyproxy/go-control-plane/pkg/server/v3"
- testv3 "github.com/envoyproxy/go-control-plane/pkg/test/v3"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/crypto"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/ratelimit"
"github.com/envoyproxy/gateway/internal/ir"
@@ -37,12 +34,20 @@ import (
const (
// XdsGrpcSotwConfigServerAddress is the listening address of the ratelimit xDS config server.
XdsGrpcSotwConfigServerAddress = "0.0.0.0"
- // rateLimitTLSCertFilename is the ratelimit tls cert file.
- rateLimitTLSCertFilename = "/certs/tls.crt"
- // rateLimitTLSKeyFilename is the ratelimit key file.
- rateLimitTLSKeyFilename = "/certs/tls.key"
- // rateLimitTLSCACertFilename is the ratelimit ca cert file.
- rateLimitTLSCACertFilename = "/certs/ca.crt"
+
+ // Default certificates path for envoy-gateway with Kubernetes provider.
+ // rateLimitTLSCertFilepath is the ratelimit tls cert file.
+ rateLimitTLSCertFilepath = "/certs/tls.crt"
+ // rateLimitTLSKeyFilepath is the ratelimit key file.
+ rateLimitTLSKeyFilepath = "/certs/tls.key"
+ // rateLimitTLSCACertFilepath is the ratelimit ca cert file.
+ rateLimitTLSCACertFilepath = "/certs/ca.crt"
+
+ // TODO: Make these path configurable.
+ // Default certificates path for envoy-gateway with Host infrastructure provider.
+ localTLSCertFilepath = "/tmp/envoy-gateway/certs/envoy-gateway/tls.crt"
+ localTLSKeyFilepath = "/tmp/envoy-gateway/certs/envoy-gateway/tls.key"
+ localTLSCaFilepath = "/tmp/envoy-gateway/certs/envoy-gateway/ca.crt"
)
type Config struct {
@@ -72,14 +77,18 @@ func (r *Runner) Start(ctx context.Context) (err error) {
// Set up the gRPC server and register the xDS handler.
// Create SnapshotCache before start subscribeAndTranslate,
// prevent panics in case cache is nil.
- cfg := r.tlsConfig(rateLimitTLSCertFilename, rateLimitTLSKeyFilename, rateLimitTLSCACertFilename)
- r.grpc = grpc.NewServer(grpc.Creds(credentials.NewTLS(cfg)))
+ tlsConfig, err := r.loadTLSConfig()
+ if err != nil {
+ return fmt.Errorf("failed to load TLS config: %w", err)
+ }
+ r.Logger.Info("loaded TLS certificate and key")
+
+ r.grpc = grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsConfig)))
r.cache = cachev3.NewSnapshotCache(false, cachev3.IDHash{}, r.Logger.Sugar())
// Register xDS Config server.
- cb := &testv3.Callbacks{}
- discoveryv3.RegisterAggregatedDiscoveryServiceServer(r.grpc, serverv3.NewServer(ctx, r.cache, cb))
+ discoveryv3.RegisterAggregatedDiscoveryServiceServer(r.grpc, serverv3.NewServer(ctx, r.cache, serverv3.CallbackFuncs{}))
// Start and listen xDS gRPC config Server.
go r.serveXdsConfigServer(ctx)
@@ -195,44 +204,22 @@ func (r *Runner) addNewSnapshot(ctx context.Context, resource types.XdsResources
return nil
}
-func (r *Runner) tlsConfig(cert, key, ca string) *tls.Config {
- loadConfig := func() (*tls.Config, error) {
- cert, err := tls.LoadX509KeyPair(cert, key)
+func (r *Runner) loadTLSConfig() (tlsConfig *tls.Config, err error) {
+ switch {
+ case r.EnvoyGateway.Provider.IsRunningOnKubernetes():
+ tlsConfig, err = crypto.LoadTLSConfig(rateLimitTLSCertFilepath, rateLimitTLSKeyFilepath, rateLimitTLSCACertFilepath)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("failed to create tls config: %w", err)
}
- // Load the CA cert.
- ca, err := os.ReadFile(ca)
+ case r.EnvoyGateway.Provider.IsRunningOnHost():
+ tlsConfig, err = crypto.LoadTLSConfig(localTLSCertFilepath, localTLSKeyFilepath, localTLSCaFilepath)
if err != nil {
- return nil, err
- }
-
- certPool := x509.NewCertPool()
- if !certPool.AppendCertsFromPEM(ca) {
- return nil, fmt.Errorf("failed to parse CA certificate")
+ return nil, fmt.Errorf("failed to create tls config: %w", err)
}
- return &tls.Config{
- Certificates: []tls.Certificate{cert},
- ClientAuth: tls.RequireAndVerifyClientCert,
- ClientCAs: certPool,
- MinVersion: tls.VersionTLS13,
- }, nil
- }
-
- // Attempt to load certificates and key to catch configuration errors early.
- if _, lerr := loadConfig(); lerr != nil {
- r.Logger.Error(lerr, "failed to load certificate and key")
- }
- r.Logger.Info("loaded TLS certificate and key")
-
- return &tls.Config{
- MinVersion: tls.VersionTLS13,
- ClientAuth: tls.RequireAndVerifyClientCert,
- Rand: rand.Reader,
- GetConfigForClient: func(*tls.ClientHelloInfo) (*tls.Config, error) {
- return loadConfig()
- },
+ default:
+ return nil, fmt.Errorf("no valid tls certificates")
}
+ return
}
diff --git a/internal/globalratelimit/runner/runner_test.go b/internal/globalratelimit/runner/runner_test.go
index e25f714792b..80598f7906e 100644
--- a/internal/globalratelimit/runner/runner_test.go
+++ b/internal/globalratelimit/runner/runner_test.go
@@ -202,7 +202,6 @@ func Test_subscribeAndTranslate(t *testing.T) {
}
for _, tt := range testCases {
- tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
diff --git a/internal/infrastructure/common/proxy_args.go b/internal/infrastructure/common/proxy_args.go
new file mode 100644
index 00000000000..165d004e5fe
--- /dev/null
+++ b/internal/infrastructure/common/proxy_args.go
@@ -0,0 +1,82 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package common
+
+import (
+ "fmt"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/xds/bootstrap"
+)
+
+func getIPFamily(infra *ir.ProxyInfra) *egv1a1.IPFamily {
+ if infra == nil || infra.Config == nil {
+ return nil
+ }
+
+ return infra.Config.Spec.IPFamily
+}
+
+// BuildProxyArgs builds command arguments for proxy infrastructure.
+func BuildProxyArgs(
+ infra *ir.ProxyInfra,
+ shutdownConfig *egv1a1.ShutdownConfig,
+ bootstrapConfigOptions *bootstrap.RenderBootstrapConfigOptions,
+ serviceNode string,
+) ([]string, error) {
+ // If IPFamily is not set, try to determine it from the infrastructure.
+ if bootstrapConfigOptions != nil && bootstrapConfigOptions.IPFamily == nil {
+ bootstrapConfigOptions.IPFamily = getIPFamily(infra)
+ }
+
+ bootstrapConfigurations, err := bootstrap.GetRenderedBootstrapConfig(bootstrapConfigOptions)
+ if err != nil {
+ return nil, err
+ }
+
+ // Apply Bootstrap from EnvoyProxy API if set by the user
+ // The config should have been validated already.
+ if infra.Config != nil && infra.Config.Spec.Bootstrap != nil {
+ bootstrapConfigurations, err = bootstrap.ApplyBootstrapConfig(infra.Config.Spec.Bootstrap, bootstrapConfigurations)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ logging := infra.Config.Spec.Logging
+
+ args := []string{
+ fmt.Sprintf("--service-cluster %s", infra.Name),
+ fmt.Sprintf("--service-node %s", serviceNode),
+ fmt.Sprintf("--config-yaml %s", bootstrapConfigurations),
+ fmt.Sprintf("--log-level %s", logging.DefaultEnvoyProxyLoggingLevel()),
+ "--cpuset-threads",
+ "--drain-strategy immediate",
+ }
+
+ if infra.Config != nil &&
+ infra.Config.Spec.Concurrency != nil {
+ args = append(args, fmt.Sprintf("--concurrency %d", *infra.Config.Spec.Concurrency))
+ }
+
+ if componentsLogLevel := logging.GetEnvoyProxyComponentLevel(); componentsLogLevel != "" {
+ args = append(args, fmt.Sprintf("--component-log-level %s", componentsLogLevel))
+ }
+
+ // Default drain timeout.
+ drainTimeout := 60.0
+ if shutdownConfig != nil && shutdownConfig.DrainTimeout != nil {
+ drainTimeout = shutdownConfig.DrainTimeout.Seconds()
+ }
+ args = append(args, fmt.Sprintf("--drain-time-s %.0f", drainTimeout))
+
+ if infra.Config != nil {
+ args = append(args, infra.Config.Spec.ExtraArgs...)
+ }
+
+ return args, nil
+}
diff --git a/internal/infrastructure/common/proxy_sds.go b/internal/infrastructure/common/proxy_sds.go
new file mode 100644
index 00000000000..ea6a9227b6e
--- /dev/null
+++ b/internal/infrastructure/common/proxy_sds.go
@@ -0,0 +1,27 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package common
+
+import "fmt"
+
+// xDS certificate rotation is supported by using SDS path-based resource files.
+
+const (
+ SdsCAFilename = "xds-trusted-ca.json"
+ SdsCertFilename = "xds-certificate.json"
+)
+
+func GetSdsCAConfigMapData(ca string) string {
+ return fmt.Sprintf(`{"resources":[{"@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",`+
+ `"name":"xds_trusted_ca","validation_context":{"trusted_ca":{"filename":"%s"},`+
+ `"match_typed_subject_alt_names":[{"san_type":"DNS","matcher":{"exact":"envoy-gateway"}}]}}]}`, ca)
+}
+
+func GetSdsCertConfigMapData(tlsCert, tlsKey string) string {
+ return fmt.Sprintf(`{"resources":[{"@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",`+
+ `"name":"xds_certificate","tls_certificate":{"certificate_chain":{"filename":"%s"},`+
+ `"private_key":{"filename":"%s"}}}]}`, tlsCert, tlsKey)
+}
diff --git a/internal/infrastructure/host/infra.go b/internal/infrastructure/host/infra.go
new file mode 100644
index 00000000000..71804561f3f
--- /dev/null
+++ b/internal/infrastructure/host/infra.go
@@ -0,0 +1,112 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package host
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "path/filepath"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/infrastructure/common"
+ "github.com/envoyproxy/gateway/internal/logging"
+ "github.com/envoyproxy/gateway/internal/utils/file"
+)
+
+const (
+ // TODO: Make these path configurable.
+ defaultHomeDir = "/tmp/envoy-gateway"
+ defaultLocalCertPathDir = "/tmp/envoy-gateway/certs/envoy"
+
+ // XdsTLSCertFilename is the fully qualified name of the file containing Envoy's
+ // xDS server TLS certificate.
+ XdsTLSCertFilename = "tls.crt"
+ // XdsTLSKeyFilename is the fully qualified name of the file containing Envoy's
+ // xDS server TLS key.
+ XdsTLSKeyFilename = "tls.key"
+ // XdsTLSCaFilename is the fully qualified name of the file containing Envoy's
+ // trusted CA certificate.
+ XdsTLSCaFilename = "ca.crt"
+)
+
+// Infra manages the creation and deletion of host process
+// based on Infra IR resources.
+type Infra struct {
+ HomeDir string
+ Logger logging.Logger
+
+ // EnvoyGateway is the configuration used to startup Envoy Gateway.
+ EnvoyGateway *egv1a1.EnvoyGateway
+
+ // proxyContextMap store the context of each running proxy by its name for lifecycle management.
+ proxyContextMap map[string]*proxyContext
+
+ // TODO: remove this field once it supports the configurable homeDir
+ sdsConfigPath string
+}
+
+func NewInfra(runnerCtx context.Context, cfg *config.Server, logger logging.Logger) (*Infra, error) {
+ // Ensure the home directory exist.
+ if err := os.MkdirAll(defaultHomeDir, 0o750); err != nil {
+ return nil, fmt.Errorf("failed to create dir: %w", err)
+ }
+
+ // Check local certificates dir exist.
+ if _, err := os.Lstat(defaultLocalCertPathDir); err != nil {
+ return nil, fmt.Errorf("failed to stat dir: %w", err)
+ }
+
+ // Ensure the sds config exist.
+ if err := createSdsConfig(defaultLocalCertPathDir); err != nil {
+ return nil, fmt.Errorf("failed to create sds config: %w", err)
+ }
+
+ infra := &Infra{
+ HomeDir: defaultHomeDir,
+ Logger: logger,
+ EnvoyGateway: cfg.EnvoyGateway,
+ proxyContextMap: make(map[string]*proxyContext),
+ sdsConfigPath: defaultLocalCertPathDir,
+ }
+ go infra.cleanProxy(runnerCtx)
+
+ return infra, nil
+}
+
+// cleanProxy stops all the running proxies when infra provider is closing.
+func (i *Infra) cleanProxy(ctx context.Context) {
+ <-ctx.Done()
+ if len(i.proxyContextMap) < 1 {
+ return
+ }
+
+ i.Logger.Info("start cleaning up proxies")
+ for name, proxyCtx := range i.proxyContextMap {
+ proxyCtx.cancel()
+ i.Logger.Info("proxy closed", "name", name)
+ }
+ i.Logger.Info("all proxies has been cleaned up")
+}
+
+// createSdsConfig creates the needing SDS config under certain directory.
+func createSdsConfig(dir string) error {
+ if err := file.Write(common.GetSdsCAConfigMapData(
+ filepath.Join(dir, XdsTLSCaFilename)),
+ filepath.Join(dir, common.SdsCAFilename)); err != nil {
+ return err
+ }
+
+ if err := file.Write(common.GetSdsCertConfigMapData(
+ filepath.Join(dir, XdsTLSCertFilename),
+ filepath.Join(dir, XdsTLSKeyFilename)),
+ filepath.Join(dir, common.SdsCertFilename)); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/internal/infrastructure/host/proxy_infra.go b/internal/infrastructure/host/proxy_infra.go
new file mode 100644
index 00000000000..371aedc2be9
--- /dev/null
+++ b/internal/infrastructure/host/proxy_infra.go
@@ -0,0 +1,89 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package host
+
+import (
+ "context"
+ "errors"
+ "path/filepath"
+
+ funcE "github.com/tetratelabs/func-e/api"
+ "k8s.io/utils/ptr"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/infrastructure/common"
+ "github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils"
+ "github.com/envoyproxy/gateway/internal/xds/bootstrap"
+)
+
+type proxyContext struct {
+ ctx context.Context
+ cancel context.CancelFunc
+}
+
+// CreateOrUpdateProxyInfra creates the managed host process, if it doesn't exist.
+func (i *Infra) CreateOrUpdateProxyInfra(ctx context.Context, infra *ir.Infra) error {
+ if infra == nil {
+ return errors.New("infra ir is nil")
+ }
+
+ if infra.Proxy == nil {
+ return errors.New("infra proxy ir is nil")
+ }
+
+ proxyInfra := infra.GetProxyInfra()
+ proxyName := utils.GetHashedName(proxyInfra.Name, 64)
+ // Return directly if the proxy is running.
+ if _, ok := i.proxyContextMap[proxyName]; ok {
+ return nil
+ }
+
+ proxyConfig := proxyInfra.GetProxyConfig()
+ // Disable Prometheus to make envoy running as a host process successfully.
+ // TODO: Add Prometheus support to host infra.
+ bootstrapConfigOptions := &bootstrap.RenderBootstrapConfigOptions{
+ ProxyMetrics: &egv1a1.ProxyMetrics{
+ Prometheus: &egv1a1.ProxyPrometheusProvider{
+ Disable: true,
+ },
+ },
+ SdsConfig: bootstrap.SdsConfigPath{
+ Certificate: filepath.Join(i.sdsConfigPath, common.SdsCertFilename),
+ TrustedCA: filepath.Join(i.sdsConfigPath, common.SdsCAFilename),
+ },
+ XdsServerHost: ptr.To("0.0.0.0"),
+ WasmServerPort: ptr.To(int32(0)),
+ AdminServerPort: ptr.To(int32(0)),
+ ReadyServerPort: ptr.To(int32(0)),
+ }
+
+ args, err := common.BuildProxyArgs(proxyInfra, proxyConfig.Spec.Shutdown, bootstrapConfigOptions, proxyName)
+ if err != nil {
+ return err
+ }
+
+ // Create a new context for up-running proxy.
+ pCtx, cancel := context.WithCancel(context.Background())
+ i.proxyContextMap[proxyName] = &proxyContext{ctx: pCtx, cancel: cancel}
+ return funcE.Run(pCtx, args, funcE.HomeDir(i.HomeDir))
+}
+
+// DeleteProxyInfra removes the managed host process, if it doesn't exist.
+func (i *Infra) DeleteProxyInfra(ctx context.Context, infra *ir.Infra) error {
+ if infra == nil {
+ return errors.New("infra ir is nil")
+ }
+
+ proxyInfra := infra.GetProxyInfra()
+ proxyName := utils.GetHashedName(proxyInfra.Name, 64)
+ if pCtx, ok := i.proxyContextMap[proxyName]; ok {
+ pCtx.cancel()
+ }
+
+ // Return directly if the proxy is already stopped.
+ return nil
+}
diff --git a/internal/infrastructure/host/proxy_infra_test.go b/internal/infrastructure/host/proxy_infra_test.go
new file mode 100644
index 00000000000..3437fe5a5d6
--- /dev/null
+++ b/internal/infrastructure/host/proxy_infra_test.go
@@ -0,0 +1,89 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package host
+
+import (
+ "context"
+ "path"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/crypto"
+ "github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/logging"
+ "github.com/envoyproxy/gateway/internal/utils/file"
+)
+
+func newMockInfra(t *testing.T, tCtx context.Context, cfg *config.Server, cleanProxy bool) *Infra {
+ t.Helper()
+ homeDir := t.TempDir()
+ // Create envoy certs under home dir.
+ certs, err := crypto.GenerateCerts(cfg)
+ require.NoError(t, err)
+ // Write certs into proxy dir.
+ proxyDir := path.Join(homeDir, "envoy")
+ err = file.WriteDir(certs.CACertificate, proxyDir, "ca.crt")
+ require.NoError(t, err)
+ err = file.WriteDir(certs.EnvoyCertificate, proxyDir, "tls.crt")
+ require.NoError(t, err)
+ err = file.WriteDir(certs.EnvoyPrivateKey, proxyDir, "tls.key")
+ require.NoError(t, err)
+ // Write sds config as well.
+ err = createSdsConfig(proxyDir)
+ require.NoError(t, err)
+
+ infra := &Infra{
+ HomeDir: homeDir,
+ Logger: logging.DefaultLogger(egv1a1.LogLevelInfo),
+ EnvoyGateway: cfg.EnvoyGateway,
+ proxyContextMap: make(map[string]*proxyContext),
+ sdsConfigPath: proxyDir,
+ }
+ if cleanProxy {
+ go infra.cleanProxy(tCtx)
+ }
+ return infra
+}
+
+func TestInfraCreateProxy(t *testing.T) {
+ cfg, err := config.New()
+ require.NoError(t, err)
+ infra := newMockInfra(t, context.Background(), cfg, true)
+
+ // TODO: add more tests once it supports configurable homeDir and runDir.
+ testCases := []struct {
+ name string
+ expect bool
+ infra *ir.Infra
+ }{
+ {
+ name: "nil cfg",
+ expect: false,
+ infra: nil,
+ },
+ {
+ name: "nil proxy",
+ expect: false,
+ infra: &ir.Infra{
+ Proxy: nil,
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ err = infra.CreateOrUpdateProxyInfra(context.Background(), tc.infra)
+ if tc.expect {
+ require.NoError(t, err)
+ } else {
+ require.Error(t, err)
+ }
+ })
+ }
+}
diff --git a/internal/infrastructure/host/ratelimit_infra.go b/internal/infrastructure/host/ratelimit_infra.go
new file mode 100644
index 00000000000..41871c9137e
--- /dev/null
+++ b/internal/infrastructure/host/ratelimit_infra.go
@@ -0,0 +1,23 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package host
+
+import (
+ "context"
+ "fmt"
+)
+
+// TODO: add ratelimit support for host infra
+
+// CreateOrUpdateRateLimitInfra creates the managed host rate limit process, if it doesn't exist.
+func (i *Infra) CreateOrUpdateRateLimitInfra(ctx context.Context) error {
+ return fmt.Errorf("create/update ratelimit infrastructure is not supported yet for host infrastructure")
+}
+
+// DeleteRateLimitInfra removes the managed host rate limit process, if it doesn't exist.
+func (i *Infra) DeleteRateLimitInfra(ctx context.Context) error {
+ return fmt.Errorf("delete ratelimit infrastructure is not supported yet for host infrastructure")
+}
diff --git a/internal/infrastructure/kubernetes/infra.go b/internal/infrastructure/kubernetes/infra.go
index 6d90b3ac342..4285f395967 100644
--- a/internal/infrastructure/kubernetes/infra.go
+++ b/internal/infrastructure/kubernetes/infra.go
@@ -13,23 +13,35 @@ import (
autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
+ "k8s.io/apimachinery/pkg/labels"
"sigs.k8s.io/controller-runtime/pkg/client"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy"
+ "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/ratelimit"
)
+var _ ResourceRender = &proxy.ResourceRender{}
+
+var _ ResourceRender = &ratelimit.ResourceRender{}
+
// ResourceRender renders Kubernetes infrastructure resources
// based on Infra IR resources.
type ResourceRender interface {
Name() string
+ LabelSelector() labels.Selector
ServiceAccount() (*corev1.ServiceAccount, error)
Service() (*corev1.Service, error)
ConfigMap() (*corev1.ConfigMap, error)
Deployment() (*appsv1.Deployment, error)
+ DeploymentSpec() (*egv1a1.KubernetesDeploymentSpec, error)
DaemonSet() (*appsv1.DaemonSet, error)
+ DaemonSetSpec() (*egv1a1.KubernetesDaemonSetSpec, error)
HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPodAutoscaler, error)
+ HorizontalPodAutoscalerSpec() (*egv1a1.KubernetesHorizontalPodAutoscalerSpec, error)
PodDisruptionBudget() (*policyv1.PodDisruptionBudget, error)
+ PodDisruptionBudgetSpec() (*egv1a1.KubernetesPodDisruptionBudgetSpec, error)
}
// Infra manages the creation and deletion of Kubernetes infrastructure
@@ -38,6 +50,9 @@ type Infra struct {
// Namespace is the Namespace used for managed infra.
Namespace string
+ // DNSDomain is the dns domain used by k8s services. Defaults to "cluster.local".
+ DNSDomain string
+
// EnvoyGateway is the configuration used to startup Envoy Gateway.
EnvoyGateway *egv1a1.EnvoyGateway
@@ -49,6 +64,7 @@ type Infra struct {
func NewInfra(cli client.Client, cfg *config.Server) *Infra {
return &Infra{
Namespace: cfg.Namespace,
+ DNSDomain: cfg.DNSDomain,
EnvoyGateway: cfg.EnvoyGateway,
Client: New(cli),
}
diff --git a/internal/infrastructure/kubernetes/infra_resource.go b/internal/infrastructure/kubernetes/infra_resource.go
index fc471f8af33..1bec17c0903 100644
--- a/internal/infrastructure/kubernetes/infra_resource.go
+++ b/internal/infrastructure/kubernetes/infra_resource.go
@@ -7,13 +7,19 @@ package kubernetes
import (
"context"
+ "fmt"
"time"
appsv1 "k8s.io/api/apps/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
+ "k8s.io/apimachinery/pkg/api/equality"
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ klabels "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/envoyproxy/gateway/internal/metrics"
)
@@ -85,6 +91,11 @@ func (i *Infra) createOrUpdateConfigMap(ctx context.Context, r ResourceRender) (
// createOrUpdateDeployment creates a Deployment in the kube api server based on the provided
// ResourceRender, if it doesn't exist and updates it if it does.
func (i *Infra) createOrUpdateDeployment(ctx context.Context, r ResourceRender) (err error) {
+ // If deployment config is nil,ignore Deployment.
+ if deploymentConfig, er := r.DeploymentSpec(); deploymentConfig == nil {
+ return er
+ }
+
var (
deployment *appsv1.Deployment
startTime = time.Now()
@@ -116,12 +127,56 @@ func (i *Infra) createOrUpdateDeployment(ctx context.Context, r ResourceRender)
}
}()
+ old := &appsv1.Deployment{}
+ err = i.Client.Get(ctx, types.NamespacedName{Name: deployment.Name, Namespace: deployment.Namespace}, old)
+ if err != nil {
+ if apierrors.IsNotFound(err) {
+ // It's the deployment creation.
+ return i.Client.ServerSideApply(ctx, deployment)
+ }
+ return err
+ }
+
+ if !equality.Semantic.DeepEqual(old.Spec.Selector, deployment.Spec.Selector) {
+ // Note: Deployment created by the old gateway controller may have a different selector generated based on a custom label feature,
+ // and it caused the issue that the gateway controller cannot update the deployment when users change the custom labels.
+ // Therefore, we changed the gateway to always use the same selector, independent of the custom labels -
+ // https://github.com/envoyproxy/gateway/issues/1818
+ //
+ // But, the change could break an existing deployment with custom labels initiated by the old gateway controller
+ // because the selector would be different.
+ //
+ // Here, as a workaround, we always copy the selector from the old deployment to the new deployment
+ // so that the update can be always applied successfully.
+ deployment.Spec.Selector = old.Spec.Selector
+
+ match, err := isSelectorMatch(deployment.Spec.Selector, deployment.Spec.Template.Labels)
+ if err != nil {
+ return err
+ }
+ if !match {
+ // If the selector now doesn't match with labels of the pod template, return an error.
+ // It could happen, for example, when users changed the custom label from {"foo": "bar"} to {"foo": "barv2"}
+ // because the pod's labels have {"foo": "barv2"} while the selector keeps {"foo": "bar"}.
+ // We cannot help this case, and just error it out.
+ // In this case, users should recreate the envoy proxy with the new custom label, instead of upgrading it.
+ // Once they recreate the envoy proxy, the envoy gateway of this version doesn't generate the selector based on the custom label,
+ // and the issue won't happen again, even if they have to the custom label again.
+ return fmt.Errorf("an illegal change in a custom label of EnvoyProxy is detected when updating %s/%s. The custom label config of deployment in EnvoyProxy, which is initiated with the envoy gateway of v1.1 or earlier, is immutable. Please recreate an envoy proxy with a new custom label if you need to change the custom label. This issue won't happen with the envoy proxy resource initialized by the envoygateway v1.2 or later", deployment.Namespace, deployment.Name)
+ }
+ }
+
return i.Client.ServerSideApply(ctx, deployment)
}
// createOrUpdateDaemonSet creates a DaemonSet in the kube api server based on the provided
// ResourceRender, if it doesn't exist and updates it if it does.
func (i *Infra) createOrUpdateDaemonSet(ctx context.Context, r ResourceRender) (err error) {
+ // If daemonset config is nil, ignore DaemonSet.
+ if daemonSetConfig, er := r.DaemonSetSpec(); daemonSetConfig == nil {
+ return er
+ }
+
var (
daemonSet *appsv1.DaemonSet
startTime = time.Now()
@@ -153,10 +208,62 @@ func (i *Infra) createOrUpdateDaemonSet(ctx context.Context, r ResourceRender) (
}
}()
+ old := &appsv1.DaemonSet{}
+ err = i.Client.Get(ctx, types.NamespacedName{Name: daemonSet.Name, Namespace: daemonSet.Namespace}, old)
+ if err != nil {
+ if apierrors.IsNotFound(err) {
+ // It's the daemonset creation.
+ return i.Client.ServerSideApply(ctx, daemonSet)
+ }
+ return err
+ }
+
+ if !equality.Semantic.DeepEqual(old.Spec.Selector, daemonSet.Spec.Selector) {
+ // Note: Daemonset created by the old gateway controller may have a different selector generated based on a custom label feature,
+ // and it caused the issue that the gateway controller cannot update the daemonset when users change the custom labels.
+ // Therefore, we changed the gateway to always use the same selector, independent of the custom labels -
+ // https://github.com/envoyproxy/gateway/issues/1818
+ //
+ // But, the change could break an existing daemonset with custom labels initiated by the old gateway controller
+ // because the selector would be different.
+ //
+ // Here, as a workaround, we always copy the selector from the old daemonset to the new daemonset
+ // so that the update can be always applied successfully.
+ daemonSet.Spec.Selector = old.Spec.Selector
+ match, err := isSelectorMatch(daemonSet.Spec.Selector, daemonSet.Spec.Template.Labels)
+ if err != nil {
+ return err
+ }
+ if !match {
+ // If the selector now doesn't match with labels of the pod template, return an error.
+ // It could happen, for example, when users changed the custom label from {"foo": "bar"} to {"foo": "barv2"}
+ // because the pod's labels have {"foo": "barv2"} while the selector keeps {"foo": "bar"}.
+ // We cannot help this case, and just error it out.
+ // In this case, users should recreate the envoy proxy with the new custom label, instead of upgrading it.
+ // Once they recreate the envoy proxy, the envoy gateway of this version doesn't generate the selector based on the custom label,
+ // and the issue won't happen again, even if they have to the custom label again.
+ return fmt.Errorf("an illegal change in a custom label of EnvoyProxy is detected when updating %s/%s. The custom label config of daemonset in EnvoyProxy, which is initiated with the envoy gateway of v1.1 or earlier, is immutable. Please recreate an envoy proxy with a new custom label if you need to change the custom label. This issue won't happen with the envoy proxy resource initialized by the envoygateway v1.2 or later", daemonSet.Namespace, daemonSet.Name)
+ }
+ }
+
return i.Client.ServerSideApply(ctx, daemonSet)
}
+func isSelectorMatch(labelselector *metav1.LabelSelector, l map[string]string) (bool, error) {
+ selector, err := metav1.LabelSelectorAsSelector(labelselector)
+ if err != nil {
+ return false, fmt.Errorf("invalid label selector is generated: %w", err)
+ }
+
+ return selector.Matches(klabels.Set(l)), nil
+}
+
func (i *Infra) createOrUpdatePodDisruptionBudget(ctx context.Context, r ResourceRender) (err error) {
+ // If podDisruptionBudget config is nil or MinAvailable is nil, ignore PodDisruptionBudget.
+ if podDisruptionBudget, er := r.PodDisruptionBudgetSpec(); podDisruptionBudget == nil {
+ return er
+ }
+
var (
pdb *policyv1.PodDisruptionBudget
startTime = time.Now()
@@ -194,6 +301,11 @@ func (i *Infra) createOrUpdatePodDisruptionBudget(ctx context.Context, r Resourc
// the provided ResourceRender, if it doesn't exist and updates it if it does,
// and delete hpa if not set.
func (i *Infra) createOrUpdateHPA(ctx context.Context, r ResourceRender) (err error) {
+ // If hpa config is nil, ignore HorizontalPodAutoscaler.
+ if hpaConfig, er := r.HorizontalPodAutoscalerSpec(); hpaConfig == nil {
+ return er
+ }
+
var (
hpa *autoscalingv2.HorizontalPodAutoscaler
startTime = time.Now()
@@ -284,11 +396,21 @@ func (i *Infra) deleteServiceAccount(ctx context.Context, r ResourceRender) (err
}
}()
- return i.Client.Delete(ctx, sa)
+ return i.Client.DeleteAllOf(ctx, sa, &client.DeleteAllOfOptions{
+ ListOptions: client.ListOptions{
+ Namespace: ns,
+ LabelSelector: r.LabelSelector(),
+ },
+ })
}
// deleteDeployment deletes the Envoy Deployment in the kube api server, if it exists.
func (i *Infra) deleteDeployment(ctx context.Context, r ResourceRender) (err error) {
+ // If deployment config is nil,ignore Deployment.
+ if deploymentConfig, er := r.DeploymentSpec(); deploymentConfig == nil {
+ return er
+ }
+
var (
name, ns = r.Name(), i.Namespace
deployment = &appsv1.Deployment{
@@ -314,11 +436,21 @@ func (i *Infra) deleteDeployment(ctx context.Context, r ResourceRender) (err err
}
}()
- return i.Client.Delete(ctx, deployment)
+ return i.Client.DeleteAllOf(ctx, deployment, &client.DeleteAllOfOptions{
+ ListOptions: client.ListOptions{
+ Namespace: ns,
+ LabelSelector: r.LabelSelector(),
+ },
+ })
}
// deleteDaemonSet deletes the Envoy DaemonSet in the kube api server, if it exists.
func (i *Infra) deleteDaemonSet(ctx context.Context, r ResourceRender) (err error) {
+ // If daemonset config is nil, ignore DaemonSet.
+ if daemonSetConfig, er := r.DaemonSetSpec(); daemonSetConfig == nil {
+ return er
+ }
+
var (
name, ns = r.Name(), i.Namespace
daemonSet = &appsv1.DaemonSet{
@@ -344,7 +476,12 @@ func (i *Infra) deleteDaemonSet(ctx context.Context, r ResourceRender) (err erro
}
}()
- return i.Client.Delete(ctx, daemonSet)
+ return i.Client.DeleteAllOf(ctx, daemonSet, &client.DeleteAllOfOptions{
+ ListOptions: client.ListOptions{
+ Namespace: ns,
+ LabelSelector: r.LabelSelector(),
+ },
+ })
}
// deleteConfigMap deletes the ConfigMap in the kube api server, if it exists.
@@ -374,7 +511,12 @@ func (i *Infra) deleteConfigMap(ctx context.Context, r ResourceRender) (err erro
}
}()
- return i.Client.Delete(ctx, cm)
+ return i.Client.DeleteAllOf(ctx, cm, &client.DeleteAllOfOptions{
+ ListOptions: client.ListOptions{
+ Namespace: ns,
+ LabelSelector: r.LabelSelector(),
+ },
+ })
}
// deleteService deletes the Service in the kube api server, if it exists.
@@ -404,11 +546,21 @@ func (i *Infra) deleteService(ctx context.Context, r ResourceRender) (err error)
}
}()
- return i.Client.Delete(ctx, svc)
+ return i.Client.DeleteAllOf(ctx, svc, &client.DeleteAllOfOptions{
+ ListOptions: client.ListOptions{
+ Namespace: ns,
+ LabelSelector: r.LabelSelector(),
+ },
+ })
}
// deleteHpa deletes the Horizontal Pod Autoscaler associated to its renderer, if it exists.
func (i *Infra) deleteHPA(ctx context.Context, r ResourceRender) (err error) {
+ // If hpa config is nil, ignore HorizontalPodAutoscaler.
+ if hpaConfig, er := r.HorizontalPodAutoscalerSpec(); hpaConfig == nil {
+ return er
+ }
+
var (
name, ns = r.Name(), i.Namespace
hpa = &autoscalingv2.HorizontalPodAutoscaler{
@@ -434,11 +586,21 @@ func (i *Infra) deleteHPA(ctx context.Context, r ResourceRender) (err error) {
}
}()
- return i.Client.Delete(ctx, hpa)
+ return i.Client.DeleteAllOf(ctx, hpa, &client.DeleteAllOfOptions{
+ ListOptions: client.ListOptions{
+ Namespace: ns,
+ LabelSelector: r.LabelSelector(),
+ },
+ })
}
// deletePDB deletes the PodDistribution budget associated to its renderer, if it exists.
func (i *Infra) deletePDB(ctx context.Context, r ResourceRender) (err error) {
+ // If podDisruptionBudget config is nil or MinAvailable is nil, ignore PodDisruptionBudget.
+ if podDisruptionBudget, er := r.PodDisruptionBudgetSpec(); podDisruptionBudget == nil {
+ return er
+ }
+
var (
name, ns = r.Name(), i.Namespace
pdb = &policyv1.PodDisruptionBudget{
@@ -464,5 +626,10 @@ func (i *Infra) deletePDB(ctx context.Context, r ResourceRender) (err error) {
}
}()
- return i.Client.Delete(ctx, pdb)
+ return i.Client.DeleteAllOf(ctx, pdb, &client.DeleteAllOfOptions{
+ ListOptions: client.ListOptions{
+ Namespace: ns,
+ LabelSelector: r.LabelSelector(),
+ },
+ })
}
diff --git a/internal/infrastructure/kubernetes/proxy/resource.go b/internal/infrastructure/kubernetes/proxy/resource.go
index f89491f4380..55b3cb10623 100644
--- a/internal/infrastructure/kubernetes/proxy/resource.go
+++ b/internal/infrastructure/kubernetes/proxy/resource.go
@@ -7,6 +7,7 @@ package proxy
import (
"fmt"
+ "path/filepath"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
@@ -15,6 +16,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/cmd/envoy"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/infrastructure/common"
"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/resource"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils"
@@ -22,17 +24,6 @@ import (
)
const (
- SdsCAFilename = "xds-trusted-ca.json"
- SdsCertFilename = "xds-certificate.json"
- // XdsTLSCertFilename is the fully qualified path of the file containing Envoy's
- // xDS server TLS certificate.
- XdsTLSCertFilename = "/certs/tls.crt"
- // XdsTLSKeyFilename is the fully qualified path of the file containing Envoy's
- // xDS server TLS key.
- XdsTLSKeyFilename = "/certs/tls.key"
- // XdsTLSCaFilename is the fully qualified path of the file containing Envoy's
- // trusted CA certificate.
- XdsTLSCaFilename = "/certs/ca.crt"
// envoyContainerName is the name of the Envoy container.
envoyContainerName = "envoy"
// envoyNsEnvVar is the name of the Envoy Gateway namespace environment variable.
@@ -41,16 +32,6 @@ const (
envoyPodEnvVar = "ENVOY_POD_NAME"
)
-var (
- // xDS certificate rotation is supported by using SDS path-based resource files.
- SdsCAConfigMapData = fmt.Sprintf(`{"resources":[{"@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",`+
- `"name":"xds_trusted_ca","validation_context":{"trusted_ca":{"filename":"%s"},`+
- `"match_typed_subject_alt_names":[{"san_type":"DNS","matcher":{"exact":"envoy-gateway"}}]}}]}`, XdsTLSCaFilename)
- SdsCertConfigMapData = fmt.Sprintf(`{"resources":[{"@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",`+
- `"name":"xds_certificate","tls_certificate":{"certificate_chain":{"filename":"%s"},`+
- `"private_key":{"filename":"%s"}}}]}`, XdsTLSCertFilename, XdsTLSKeyFilename)
-)
-
// ExpectedResourceHashedName returns expected resource hashed name including up to the 48 characters of the original name.
func ExpectedResourceHashedName(name string) string {
hashedName := utils.GetHashedName(name, 48)
@@ -102,31 +83,12 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
containerSpec *egv1a1.KubernetesContainerSpec,
shutdownConfig *egv1a1.ShutdownConfig,
shutdownManager *egv1a1.ShutdownManager,
+ namespace string,
+ dnsDomain string,
) ([]corev1.Container, error) {
// Define slice to hold container ports
var ports []corev1.ContainerPort
- // Iterate over listeners and ports to get container ports
- for _, listener := range infra.Listeners {
- for _, p := range listener.Ports {
- var protocol corev1.Protocol
- switch p.Protocol {
- case ir.HTTPProtocolType, ir.HTTPSProtocolType, ir.TLSProtocolType, ir.TCPProtocolType:
- protocol = corev1.ProtocolTCP
- case ir.UDPProtocolType:
- protocol = corev1.ProtocolUDP
- default:
- return nil, fmt.Errorf("invalid protocol %q", p.Protocol)
- }
- port := corev1.ContainerPort{
- Name: p.Name,
- ContainerPort: p.ContainerPort,
- Protocol: protocol,
- }
- ports = append(ports, port)
- }
- }
-
if enablePrometheus(infra) {
ports = append(ports, corev1.ContainerPort{
Name: "metrics",
@@ -135,8 +97,6 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
})
}
- var bootstrapConfigurations string
-
var proxyMetrics *egv1a1.ProxyMetrics
if infra.Config != nil &&
infra.Config.Spec.Telemetry != nil {
@@ -146,48 +106,19 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
maxHeapSizeBytes := calculateMaxHeapSizeBytes(containerSpec.Resources)
// Get the default Bootstrap
- bootstrapConfigurations, err := bootstrap.GetRenderedBootstrapConfig(&bootstrap.RenderBootstrapConfigOptions{
- ProxyMetrics: proxyMetrics,
+ bootstrapConfigOptions := &bootstrap.RenderBootstrapConfigOptions{
+ ProxyMetrics: proxyMetrics,
+ SdsConfig: bootstrap.SdsConfigPath{
+ Certificate: filepath.Join("/sds", common.SdsCertFilename),
+ TrustedCA: filepath.Join("/sds", common.SdsCAFilename),
+ },
MaxHeapSizeBytes: maxHeapSizeBytes,
- })
- if err != nil {
- return nil, err
- }
-
- // Apply Bootstrap from EnvoyProxy API if set by the user
- // The config should have been validated already
- if infra.Config != nil && infra.Config.Spec.Bootstrap != nil {
- bootstrapConfigurations, err = bootstrap.ApplyBootstrapConfig(infra.Config.Spec.Bootstrap, bootstrapConfigurations)
- if err != nil {
- return nil, err
- }
- }
-
- logging := infra.Config.Spec.Logging
-
- args := []string{
- fmt.Sprintf("--service-cluster %s", infra.Name),
- fmt.Sprintf("--service-node $(%s)", envoyPodEnvVar),
- fmt.Sprintf("--config-yaml %s", bootstrapConfigurations),
- fmt.Sprintf("--log-level %s", logging.DefaultEnvoyProxyLoggingLevel()),
- "--cpuset-threads",
- }
-
- if infra.Config != nil &&
- infra.Config.Spec.Concurrency != nil {
- args = append(args, fmt.Sprintf("--concurrency %d", *infra.Config.Spec.Concurrency))
- }
-
- if componentsLogLevel := logging.GetEnvoyProxyComponentLevel(); componentsLogLevel != "" {
- args = append(args, fmt.Sprintf("--component-log-level %s", componentsLogLevel))
- }
-
- if shutdownConfig != nil && shutdownConfig.DrainTimeout != nil {
- args = append(args, fmt.Sprintf("--drain-time-s %.0f", shutdownConfig.DrainTimeout.Seconds()))
+ XdsServerHost: ptr.To(fmt.Sprintf("%s.%s.svc.%s", config.EnvoyGatewayServiceName, namespace, dnsDomain)),
}
- if infra.Config != nil {
- args = append(args, infra.Config.Spec.ExtraArgs...)
+ args, err := common.BuildProxyArgs(infra, shutdownConfig, bootstrapConfigOptions, fmt.Sprintf("$(%s)", envoyPodEnvVar))
+ if err != nil {
+ return nil, err
}
containers := []corev1.Container{
@@ -199,7 +130,7 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
Args: args,
Env: expectedContainerEnv(containerSpec),
Resources: *containerSpec.Resources,
- SecurityContext: containerSpec.SecurityContext,
+ SecurityContext: expectedEnvoySecurityContext(containerSpec),
Ports: ports,
VolumeMounts: expectedContainerVolumeMounts(containerSpec),
TerminationMessagePolicy: corev1.TerminationMessageReadFile,
@@ -226,9 +157,9 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
},
},
TimeoutSeconds: 1,
- PeriodSeconds: 10,
+ PeriodSeconds: 5,
SuccessThreshold: 1,
- FailureThreshold: 3,
+ FailureThreshold: 1,
},
Lifecycle: &corev1.Lifecycle{
PreStop: &corev1.LifecycleHandler{
@@ -296,6 +227,7 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
},
},
},
+ SecurityContext: expectedShutdownManagerSecurityContext(),
},
}
@@ -373,12 +305,12 @@ func expectedVolumes(name string, pod *egv1a1.KubernetesPodSpec) []corev1.Volume
},
Items: []corev1.KeyToPath{
{
- Key: SdsCAFilename,
- Path: SdsCAFilename,
+ Key: common.SdsCAFilename,
+ Path: common.SdsCAFilename,
},
{
- Key: SdsCertFilename,
- Path: SdsCertFilename,
+ Key: common.SdsCertFilename,
+ Path: common.SdsCertFilename,
},
},
DefaultMode: ptr.To[int32](420),
@@ -435,3 +367,32 @@ func calculateMaxHeapSizeBytes(envoyResourceRequirements *corev1.ResourceRequire
return 0
}
+
+func expectedEnvoySecurityContext(containerSpec *egv1a1.KubernetesContainerSpec) *corev1.SecurityContext {
+ if containerSpec != nil && containerSpec.SecurityContext != nil {
+ return containerSpec.SecurityContext
+ }
+
+ sc := resource.DefaultSecurityContext()
+
+ // run as non-root user
+ sc.RunAsGroup = ptr.To(int64(65532))
+ sc.RunAsUser = ptr.To(int64(65532))
+
+ // Envoy container needs to write to the log file/UDS socket.
+ sc.ReadOnlyRootFilesystem = nil
+ return sc
+}
+
+func expectedShutdownManagerSecurityContext() *corev1.SecurityContext {
+ sc := resource.DefaultSecurityContext()
+
+ // run as non-root user
+ sc.RunAsGroup = ptr.To(int64(65532))
+ sc.RunAsUser = ptr.To(int64(65532))
+
+ // ShutdownManger creates a file to indicate the connection drain process is completed,
+ // so it needs file write permission.
+ sc.ReadOnlyRootFilesystem = nil
+ return sc
+}
diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider.go b/internal/infrastructure/kubernetes/proxy/resource_provider.go
index e48122b62ea..9c25886a6bf 100644
--- a/internal/infrastructure/kubernetes/proxy/resource_provider.go
+++ b/internal/infrastructure/kubernetes/proxy/resource_provider.go
@@ -15,28 +15,46 @@ import (
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/ptr"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/infrastructure/common"
"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/resource"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/xds/bootstrap"
)
+const (
+ // XdsTLSCertFilepath is the fully qualified path of the file containing Envoy's
+ // xDS server TLS certificate.
+ XdsTLSCertFilepath = "/certs/tls.crt"
+ // XdsTLSKeyFilepath is the fully qualified path of the file containing Envoy's
+ // xDS server TLS key.
+ XdsTLSKeyFilepath = "/certs/tls.key"
+ // XdsTLSCaFilepath is the fully qualified path of the file containing Envoy's
+ // trusted CA certificate.
+ XdsTLSCaFilepath = "/certs/ca.crt"
+)
+
type ResourceRender struct {
infra *ir.ProxyInfra
// Namespace is the Namespace used for managed infra.
Namespace string
+ // DNSDomain is the dns domain used by k8s services. Defaults to "cluster.local".
+ DNSDomain string
+
ShutdownManager *egv1a1.ShutdownManager
}
-func NewResourceRender(ns string, infra *ir.ProxyInfra, gateway *egv1a1.EnvoyGateway) *ResourceRender {
+func NewResourceRender(ns string, dnsDomain string, infra *ir.ProxyInfra, gateway *egv1a1.EnvoyGateway) *ResourceRender {
return &ResourceRender{
Namespace: ns,
+ DNSDomain: dnsDomain,
infra: infra,
ShutdownManager: gateway.GetEnvoyGatewayProvider().GetEnvoyGatewayKubeProvider().ShutdownManager,
}
@@ -46,6 +64,10 @@ func (r *ResourceRender) Name() string {
return ExpectedResourceHashedName(r.infra.Name)
}
+func (r *ResourceRender) LabelSelector() labels.Selector {
+ return labels.SelectorFromSet(r.stableSelector().MatchLabels)
+}
+
// ServiceAccount returns the expected proxy serviceAccount.
func (r *ResourceRender) ServiceAccount() (*corev1.ServiceAccount, error) {
// Set the labels based on the owning gateway name.
@@ -101,10 +123,10 @@ func (r *ResourceRender) Service() (*corev1.Service, error) {
}
}
- // Set the labels based on the owning gatewayclass name.
- labels := envoyLabels(r.infra.GetProxyMetadata().Labels)
- if OwningGatewayLabelsAbsent(labels) {
- return nil, fmt.Errorf("missing owning gateway labels")
+ // Set the infraLabels based on the owning gatewayclass name.
+ infraLabels := envoyLabels(r.infra.GetProxyMetadata().Labels)
+ if OwningGatewayLabelsAbsent(infraLabels) {
+ return nil, fmt.Errorf("missing owning gateway infraLabels")
}
// Get annotations
@@ -120,10 +142,20 @@ func (r *ResourceRender) Service() (*corev1.Service, error) {
annotations = nil
}
+ // Get service-specific labels
+ svcLabels := map[string]string{}
+ maps.Copy(svcLabels, infraLabels)
+ if envoyServiceConfig.Labels != nil {
+ maps.Copy(svcLabels, envoyServiceConfig.Labels)
+ }
+ if len(svcLabels) == 0 {
+ svcLabels = nil
+ }
+
// Set the spec of gateway service
serviceSpec := resource.ExpectedServiceSpec(envoyServiceConfig)
serviceSpec.Ports = ports
- serviceSpec.Selector = resource.GetSelector(labels).MatchLabels
+ serviceSpec.Selector = resource.GetSelector(infraLabels).MatchLabels
if (*envoyServiceConfig.Type) == egv1a1.ServiceTypeClusterIP {
if len(r.infra.Addresses) > 0 {
@@ -144,7 +176,7 @@ func (r *ResourceRender) Service() (*corev1.Service, error) {
},
ObjectMeta: metav1.ObjectMeta{
Namespace: r.Namespace,
- Labels: labels,
+ Labels: svcLabels,
Annotations: annotations,
},
Spec: serviceSpec,
@@ -186,14 +218,27 @@ func (r *ResourceRender) ConfigMap() (*corev1.ConfigMap, error) {
Annotations: r.infra.GetProxyMetadata().Annotations,
},
Data: map[string]string{
- SdsCAFilename: SdsCAConfigMapData,
- SdsCertFilename: SdsCertConfigMapData,
+ common.SdsCAFilename: common.GetSdsCAConfigMapData(XdsTLSCaFilepath),
+ common.SdsCertFilename: common.GetSdsCertConfigMapData(XdsTLSCertFilepath, XdsTLSKeyFilepath),
},
}, nil
}
-// Deployment returns the expected Deployment based on the provided infra.
-func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
+// stableSelector returns a stable selector based on the owning gateway labels.
+// "stable" here means the selector doesn't change when the infra is updated.
+func (r *ResourceRender) stableSelector() *metav1.LabelSelector {
+ labels := map[string]string{}
+ for k, v := range r.infra.GetProxyMetadata().Labels {
+ if k == gatewayapi.OwningGatewayNameLabel || k == gatewayapi.OwningGatewayNamespaceLabel || k == gatewayapi.OwningGatewayClassLabel {
+ labels[k] = v
+ }
+ }
+
+ return resource.GetSelector(envoyLabels(labels))
+}
+
+// DeploymentSpec returns the `Deployment` sets spec.
+func (r *ResourceRender) DeploymentSpec() (*egv1a1.KubernetesDeploymentSpec, error) {
proxyConfig := r.infra.GetProxyConfig()
// Get the EnvoyProxy config to configure the deployment.
@@ -201,15 +246,23 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
if provider.Type != egv1a1.ProviderTypeKubernetes {
return nil, fmt.Errorf("invalid provider type %v for Kubernetes infra manager", provider.Type)
}
+
deploymentConfig := provider.GetEnvoyProxyKubeProvider().EnvoyDeployment
- // If deployment config is nil, it's not Deployment installation.
+ return deploymentConfig, nil
+}
+
+// Deployment returns the expected Deployment based on the provided infra.
+func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
+ deploymentConfig, er := r.DeploymentSpec()
+ // If deployment config is nil,ignore Deployment.
if deploymentConfig == nil {
- return nil, nil
+ return nil, er
}
+ proxyConfig := r.infra.GetProxyConfig()
// Get expected bootstrap configurations rendered ProxyContainers
- containers, err := expectedProxyContainers(r.infra, deploymentConfig.Container, proxyConfig.Spec.Shutdown, r.ShutdownManager)
+ containers, err := expectedProxyContainers(r.infra, deploymentConfig.Container, proxyConfig.Spec.Shutdown, r.ShutdownManager, r.Namespace, r.DNSDomain)
if err != nil {
return nil, err
}
@@ -222,8 +275,6 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
if err != nil {
return nil, err
}
- podLabels := r.getPodLabels(deploymentConfig.Pod)
- selector := resource.GetSelector(podLabels)
deployment := &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
@@ -238,16 +289,17 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
Spec: appsv1.DeploymentSpec{
Replicas: deploymentConfig.Replicas,
Strategy: *deploymentConfig.Strategy,
- Selector: selector,
+ // Deployment's selector is immutable.
+ Selector: r.stableSelector(),
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
- Labels: selector.MatchLabels,
+ Labels: r.getPodLabels(deploymentConfig.Pod),
Annotations: podAnnotations,
},
Spec: corev1.PodSpec{
Containers: containers,
InitContainers: deploymentConfig.InitContainers,
- ServiceAccountName: ExpectedResourceHashedName(r.infra.Name),
+ ServiceAccountName: r.Name(),
AutomountServiceAccountToken: ptr.To(false),
TerminationGracePeriodSeconds: expectedTerminationGracePeriodSeconds(proxyConfig.Spec.Shutdown),
DNSPolicy: corev1.DNSClusterFirst,
@@ -274,6 +326,8 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
deployment.ObjectMeta.Name = r.Name()
}
+ provider := proxyConfig.GetEnvoyProxyProvider()
+
// omit the deployment replicas if HPA is being set
if provider.GetEnvoyProxyKubeProvider().EnvoyHpa != nil {
deployment.Spec.Replicas = nil
@@ -287,7 +341,8 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
return deployment, nil
}
-func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) {
+// DaemonSetSpec returns the `DaemonSet` sets spec.
+func (r *ResourceRender) DaemonSetSpec() (*egv1a1.KubernetesDaemonSetSpec, error) {
proxyConfig := r.infra.GetProxyConfig()
// Get the EnvoyProxy config to configure the daemonset.
@@ -296,15 +351,20 @@ func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) {
return nil, fmt.Errorf("invalid provider type %v for Kubernetes infra manager", provider.Type)
}
- daemonSetConfig := provider.GetEnvoyProxyKubeProvider().EnvoyDaemonSet
+ return provider.GetEnvoyProxyKubeProvider().EnvoyDaemonSet, nil
+}
- // If daemonset config is nil, it's not DaemonSet installation.
+func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) {
+ daemonSetConfig, err := r.DaemonSetSpec()
+ // If daemonset config is nil, ignore DaemonSet.
if daemonSetConfig == nil {
- return nil, nil
+ return nil, err
}
+ proxyConfig := r.infra.GetProxyConfig()
+
// Get expected bootstrap configurations rendered ProxyContainers
- containers, err := expectedProxyContainers(r.infra, daemonSetConfig.Container, proxyConfig.Spec.Shutdown, r.ShutdownManager)
+ containers, err := expectedProxyContainers(r.infra, daemonSetConfig.Container, proxyConfig.Spec.Shutdown, r.ShutdownManager, r.Namespace, r.DNSDomain)
if err != nil {
return nil, err
}
@@ -317,8 +377,6 @@ func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) {
if err != nil {
return nil, err
}
- podLabels := r.getPodLabels(daemonSetConfig.Pod)
- selector := resource.GetSelector(podLabels)
daemonSet := &appsv1.DaemonSet{
TypeMeta: metav1.TypeMeta{
@@ -331,11 +389,12 @@ func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) {
Annotations: dsAnnotations,
},
Spec: appsv1.DaemonSetSpec{
- Selector: selector,
+ // Daemonset's selector is immutable.
+ Selector: r.stableSelector(),
UpdateStrategy: *daemonSetConfig.Strategy,
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
- Labels: selector.MatchLabels,
+ Labels: r.getPodLabels(daemonSetConfig.Pod),
Annotations: podAnnotations,
},
Spec: r.getPodSpec(containers, nil, daemonSetConfig.Pod, proxyConfig),
@@ -358,7 +417,8 @@ func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) {
return daemonSet, nil
}
-func (r *ResourceRender) PodDisruptionBudget() (*policyv1.PodDisruptionBudget, error) {
+// PodDisruptionBudgetSpec returns the `PodDisruptionBudget` sets spec.
+func (r *ResourceRender) PodDisruptionBudgetSpec() (*egv1a1.KubernetesPodDisruptionBudgetSpec, error) {
provider := r.infra.GetProxyConfig().GetEnvoyProxyProvider()
if provider.Type != egv1a1.ProviderTypeKubernetes {
return nil, fmt.Errorf("invalid provider type %v for Kubernetes infra manager", provider.Type)
@@ -369,12 +429,17 @@ func (r *ResourceRender) PodDisruptionBudget() (*policyv1.PodDisruptionBudget, e
return nil, nil
}
- labels, err := r.getLabels()
- if err != nil {
+ return podDisruptionBudget, nil
+}
+
+func (r *ResourceRender) PodDisruptionBudget() (*policyv1.PodDisruptionBudget, error) {
+ podDisruptionBudgetConfig, err := r.PodDisruptionBudgetSpec()
+ // If podDisruptionBudget config is nil or MinAvailable is nil, ignore PodDisruptionBudget.
+ if podDisruptionBudgetConfig == nil {
return nil, err
}
- return &policyv1.PodDisruptionBudget{
+ podDisruptionBudget := &policyv1.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{
Name: r.Name(),
Namespace: r.Namespace,
@@ -384,23 +449,35 @@ func (r *ResourceRender) PodDisruptionBudget() (*policyv1.PodDisruptionBudget, e
Kind: "PodDisruptionBudget",
},
Spec: policyv1.PodDisruptionBudgetSpec{
- MinAvailable: &intstr.IntOrString{IntVal: ptr.Deref(podDisruptionBudget.MinAvailable, 0)},
- Selector: &metav1.LabelSelector{
- MatchLabels: labels,
- },
+ MinAvailable: &intstr.IntOrString{IntVal: ptr.Deref(podDisruptionBudgetConfig.MinAvailable, 0)},
+ Selector: r.stableSelector(),
},
- }, nil
+ }
+
+ // apply merge patch to PodDisruptionBudget
+ if podDisruptionBudget, err = podDisruptionBudgetConfig.ApplyMergePatch(podDisruptionBudget); err != nil {
+ return nil, err
+ }
+
+ return podDisruptionBudget, nil
}
-func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPodAutoscaler, error) {
+// HorizontalPodAutoscalerSpec returns the `HorizontalPodAutoscaler` sets spec.
+func (r *ResourceRender) HorizontalPodAutoscalerSpec() (*egv1a1.KubernetesHorizontalPodAutoscalerSpec, error) {
provider := r.infra.GetProxyConfig().GetEnvoyProxyProvider()
if provider.Type != egv1a1.ProviderTypeKubernetes {
return nil, fmt.Errorf("invalid provider type %v for Kubernetes infra manager", provider.Type)
}
hpaConfig := provider.GetEnvoyProxyKubeProvider().EnvoyHpa
+ return hpaConfig, nil
+}
+
+func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPodAutoscaler, error) {
+ hpaConfig, err := r.HorizontalPodAutoscalerSpec()
+ // If hpa config is nil, ignore HorizontalPodAutoscaler.
if hpaConfig == nil {
- return nil, nil
+ return nil, err
}
hpa := &autoscalingv2.HorizontalPodAutoscaler{
@@ -426,6 +503,8 @@ func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPod
},
}
+ provider := r.infra.GetProxyConfig().GetEnvoyProxyProvider()
+
// set deployment target ref name
deploymentConfig := provider.GetEnvoyProxyKubeProvider().EnvoyDeployment
if deploymentConfig.Name != nil {
@@ -434,11 +513,15 @@ func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPod
hpa.Spec.ScaleTargetRef.Name = r.Name()
}
+ if hpa, err = hpaConfig.ApplyMergePatch(hpa); err != nil {
+ return nil, err
+ }
+
return hpa, nil
}
func expectedTerminationGracePeriodSeconds(cfg *egv1a1.ShutdownConfig) *int64 {
- s := 900 // default
+ s := 360 // default
if cfg != nil && cfg.DrainTimeout != nil {
s = int(cfg.DrainTimeout.Seconds() + 300) // 5 minutes longer than drain timeout
}
diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go
index 16c94d037a4..0f5f6e3bf27 100644
--- a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go
+++ b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go
@@ -44,6 +44,26 @@ func newTestInfra() *ir.Infra {
return newTestInfraWithAnnotations(nil)
}
+func newTestIPv6Infra() *ir.Infra {
+ i := newTestInfra()
+ i.Proxy.Config = &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ IPFamily: ptr.To(egv1a1.IPv6),
+ },
+ }
+ return i
+}
+
+func newTestDualStackInfra() *ir.Infra {
+ i := newTestInfra()
+ i.Proxy.Config = &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ IPFamily: ptr.To(egv1a1.DualStack),
+ },
+ }
+ return i
+}
+
func newTestInfraWithAnnotations(annotations map[string]string) *ir.Infra {
return newTestInfraWithAnnotationsAndLabels(annotations, nil)
}
@@ -200,6 +220,16 @@ func TestDeployment(t *testing.T) {
deploy: nil,
bootstrap: `test bootstrap config`,
},
+ {
+ caseName: "ipv6",
+ infra: newTestIPv6Infra(),
+ deploy: nil,
+ },
+ {
+ caseName: "dual-stack",
+ infra: newTestDualStackInfra(),
+ deploy: nil,
+ },
{
caseName: "extension-env",
infra: newTestInfra(),
@@ -529,9 +559,10 @@ func TestDeployment(t *testing.T) {
replace := egv1a1.BootstrapTypeReplace
if tc.bootstrap != "" {
+ bsValue := tc.bootstrap
tc.infra.Proxy.Config.Spec.Bootstrap = &egv1a1.ProxyBootstrap{
Type: &replace,
- Value: tc.bootstrap,
+ Value: &bsValue,
}
}
@@ -563,19 +594,10 @@ func TestDeployment(t *testing.T) {
tc.infra.Proxy.Config.Spec.ExtraArgs = tc.extraArgs
}
- r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
+ r := NewResourceRender(cfg.Namespace, cfg.DNSDomain, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
dp, err := r.Deployment()
require.NoError(t, err)
- expected, err := loadDeployment(tc.caseName)
- require.NoError(t, err)
-
- sortEnv := func(env []corev1.EnvVar) {
- sort.Slice(env, func(i, j int) bool {
- return env[i].Name > env[j].Name
- })
- }
-
if *overrideTestData {
deploymentYAML, err := yaml.Marshal(dp)
require.NoError(t, err)
@@ -585,8 +607,17 @@ func TestDeployment(t *testing.T) {
return
}
+ expected, err := loadDeployment(tc.caseName)
+ require.NoError(t, err)
+
+ sortEnv := func(env []corev1.EnvVar) {
+ sort.Slice(env, func(i, j int) bool {
+ return env[i].Name > env[j].Name
+ })
+ }
sortEnv(dp.Spec.Template.Spec.Containers[0].Env)
sortEnv(expected.Spec.Template.Spec.Containers[0].Env)
+
assert.Equal(t, expected, dp)
})
}
@@ -963,9 +994,10 @@ func TestDaemonSet(t *testing.T) {
replace := egv1a1.BootstrapTypeReplace
if tc.bootstrap != "" {
+ bsValue := tc.bootstrap
tc.infra.Proxy.Config.Spec.Bootstrap = &egv1a1.ProxyBootstrap{
Type: &replace,
- Value: tc.bootstrap,
+ Value: &bsValue,
}
}
@@ -991,7 +1023,7 @@ func TestDaemonSet(t *testing.T) {
tc.infra.Proxy.Config.Spec.ExtraArgs = tc.extraArgs
}
- r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
+ r := NewResourceRender(cfg.Namespace, cfg.DNSDomain, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
ds, err := r.DaemonSet()
require.NoError(t, err)
@@ -1049,6 +1081,9 @@ func TestService(t *testing.T) {
caseName: "custom",
infra: newTestInfra(),
service: &egv1a1.KubernetesServiceSpec{
+ Labels: map[string]string{
+ "key1": "value1",
+ },
Annotations: map[string]string{
"key1": "value1",
},
@@ -1077,6 +1112,31 @@ func TestService(t *testing.T) {
},
},
},
+ {
+ caseName: "with-svc-labels",
+ infra: newTestInfra(),
+ service: &egv1a1.KubernetesServiceSpec{
+ Labels: map[string]string{
+ "label1": "value1",
+ "label2": "value2",
+ },
+ },
+ },
+ {
+ caseName: "override-labels",
+ infra: newTestInfraWithAnnotationsAndLabels(map[string]string{
+ "anno1": "value1",
+ "anno2": "value2",
+ }, map[string]string{
+ "label1": "value1",
+ "label2": "value2",
+ }),
+ service: &egv1a1.KubernetesServiceSpec{
+ Labels: map[string]string{
+ "label1": "value1-override",
+ },
+ },
+ },
{
caseName: "clusterIP-custom-addresses",
infra: newTestInfraWithAddresses([]string{
@@ -1113,7 +1173,7 @@ func TestService(t *testing.T) {
provider.EnvoyService = tc.service
}
- r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
+ r := NewResourceRender(cfg.Namespace, cfg.DNSDomain, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
svc, err := r.Service()
require.NoError(t, err)
@@ -1156,7 +1216,7 @@ func TestConfigMap(t *testing.T) {
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
- r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
+ r := NewResourceRender(cfg.Namespace, cfg.DNSDomain, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
cm, err := r.ConfigMap()
require.NoError(t, err)
@@ -1199,7 +1259,7 @@ func TestServiceAccount(t *testing.T) {
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
- r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
+ r := NewResourceRender(cfg.Namespace, cfg.DNSDomain, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
sa, err := r.ServiceAccount()
require.NoError(t, err)
@@ -1238,6 +1298,32 @@ func TestPDB(t *testing.T) {
MinAvailable: ptr.To(int32(1)),
},
},
+ {
+ caseName: "patch-json-pdb",
+ infra: newTestInfra(),
+ pdb: &egv1a1.KubernetesPodDisruptionBudgetSpec{
+ MinAvailable: ptr.To(int32(1)),
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Type: ptr.To(egv1a1.JSONMerge),
+ Value: apiextensionsv1.JSON{
+ Raw: []byte("{\"metadata\":{\"name\":\"foo\"}, \"spec\": {\"selector\": {\"matchLabels\": {\"app\": \"bar\"}}}}"),
+ },
+ },
+ },
+ },
+ {
+ caseName: "patch-strategic-pdb",
+ infra: newTestInfra(),
+ pdb: &egv1a1.KubernetesPodDisruptionBudgetSpec{
+ MinAvailable: ptr.To(int32(1)),
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Type: ptr.To(egv1a1.StrategicMerge),
+ Value: apiextensionsv1.JSON{
+ Raw: []byte("{\"metadata\":{\"name\":\"foo\"}, \"spec\": {\"selector\": {\"matchLabels\": {\"app\": \"bar\"}}}}"),
+ },
+ },
+ },
+ },
}
for _, tc := range cases {
@@ -1255,7 +1341,7 @@ func TestPDB(t *testing.T) {
provider.GetEnvoyProxyKubeProvider()
- r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
+ r := NewResourceRender(cfg.Namespace, cfg.DNSDomain, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
pdb, err := r.PodDisruptionBudget()
require.NoError(t, err)
@@ -1315,6 +1401,32 @@ func TestHorizontalPodAutoscaler(t *testing.T) {
},
},
},
+ {
+ caseName: "patch-json-hpa",
+ infra: newTestInfra(),
+ hpa: &egv1a1.KubernetesHorizontalPodAutoscalerSpec{
+ MaxReplicas: ptr.To[int32](1),
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Type: ptr.To(egv1a1.JSONMerge),
+ Value: apiextensionsv1.JSON{
+ Raw: []byte("{\"metadata\":{\"name\":\"foo\"}, \"spec\": {\"scaleTargetRef\": {\"name\": \"bar\"}}}"),
+ },
+ },
+ },
+ },
+ {
+ caseName: "patch-strategic-hpa",
+ infra: newTestInfra(),
+ hpa: &egv1a1.KubernetesHorizontalPodAutoscalerSpec{
+ MaxReplicas: ptr.To[int32](1),
+ Patch: &egv1a1.KubernetesPatchSpec{
+ Type: ptr.To(egv1a1.StrategicMerge),
+ Value: apiextensionsv1.JSON{
+ Raw: []byte("{\"metadata\":{\"name\":\"foo\"}, \"spec\": {\"metrics\": [{\"resource\": {\"name\": \"cpu\", \"target\": {\"averageUtilization\": 50, \"type\": \"Utilization\"}}, \"type\": \"Resource\"}]}}"),
+ },
+ },
+ },
+ },
{
caseName: "with-deployment-name",
infra: newTestInfra(),
@@ -1341,7 +1453,7 @@ func TestHorizontalPodAutoscaler(t *testing.T) {
}
provider.GetEnvoyProxyKubeProvider()
- r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
+ r := NewResourceRender(cfg.Namespace, cfg.DNSDomain, tc.infra.GetProxyInfra(), cfg.EnvoyGateway)
hpa, err := r.HorizontalPodAutoscaler()
require.NoError(t, err)
diff --git a/internal/infrastructure/kubernetes/proxy/resource_test.go b/internal/infrastructure/kubernetes/proxy/resource_test.go
index 3cf71f2aea2..31054b1ef1d 100644
--- a/internal/infrastructure/kubernetes/proxy/resource_test.go
+++ b/internal/infrastructure/kubernetes/proxy/resource_test.go
@@ -30,7 +30,6 @@ func TestEnvoyPodSelector(t *testing.T) {
}
for _, tc := range cases {
- tc := tc
t.Run("", func(t *testing.T) {
got := envoyLabels(tc.in)
require.Equal(t, tc.expected, got)
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
index 99d32ac0a39..5b0f132f0b9 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
@@ -40,7 +40,9 @@ spec:
- --config-yaml test bootstrap config
- --log-level error
- --cpuset-threads
+ - --drain-strategy immediate
- --component-log-level filter:info
+ - --drain-time-s 60
command:
- envoy
env:
@@ -54,7 +56,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -64,28 +66,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -119,7 +126,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -151,6 +158,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -166,7 +184,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
index fc524284fb4..87727e4be1c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
@@ -16,7 +16,6 @@ spec:
app.kubernetes.io/component: proxy
app.kubernetes.io/managed-by: envoy-gateway
app.kubernetes.io/name: envoy
- foo.bar: custom-label
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
template:
@@ -76,7 +75,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -132,7 +131,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -155,13 +154,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -193,13 +192,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -225,6 +224,8 @@ spec:
value: 0.98
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -248,22 +249,16 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -308,7 +303,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -340,6 +335,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -357,7 +363,7 @@ spec:
securityContext:
runAsUser: 1000
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
index fbeddc169b8..7827b9eccc7 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -223,6 +223,8 @@ spec:
value: 0.98
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -246,22 +248,16 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -306,7 +302,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -338,6 +334,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -355,7 +362,7 @@ spec:
securityContext:
runAsUser: 1000
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
index 12a23303837..95f186cb8a4 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -208,6 +208,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -221,7 +223,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -231,28 +233,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -286,7 +293,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -318,6 +325,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -333,7 +351,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
index 8e0e734fead..54e8c6d53f4 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
@@ -70,7 +70,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -104,7 +104,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -127,13 +127,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -165,13 +165,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -182,6 +182,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -195,7 +197,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -204,26 +206,30 @@ spec:
port: 19002
scheme: HTTP
name: envoy
- ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -257,7 +263,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -289,6 +295,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -304,7 +321,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
index 314e8bcea7a..b75e8ec22ad 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -223,6 +223,8 @@ spec:
value: 0.98
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -250,22 +252,16 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -310,7 +306,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -342,6 +338,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -359,7 +366,7 @@ spec:
securityContext:
runAsUser: 1000
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
index 1707fe03ff2..1d033190e83 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
@@ -23,8 +23,6 @@ spec:
app.kubernetes.io/name: envoy
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
- label1: value1-override
- label2: value2
template:
metadata:
annotations:
@@ -85,7 +83,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -141,7 +139,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -164,13 +162,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -202,13 +200,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -219,6 +217,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -232,7 +232,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -242,28 +242,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -297,7 +302,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -329,6 +334,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -344,7 +360,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
index c830cff8176..0e9f6e598c7 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -208,6 +208,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -221,7 +223,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -231,28 +233,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -286,7 +293,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -318,6 +325,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -334,7 +352,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
index 7c2c2755a70..99647fce436 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -208,6 +208,7 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
- --drain-time-s 30
command:
- envoy
@@ -222,7 +223,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -232,28 +233,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -330,7 +336,16 @@ spec:
cpu: 100m
memory: 64Mi
securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
runAsUser: 1234
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
index fc59ec6739b..53ec48429c1 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -223,6 +223,8 @@ spec:
value: 0.98
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -250,22 +252,16 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -310,7 +306,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -342,6 +338,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -359,7 +366,7 @@ spec:
securityContext:
runAsUser: 1000
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
index a0ee70d91eb..b9beaa023ff 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
@@ -79,7 +79,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -135,7 +135,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -158,13 +158,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -196,13 +196,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -213,6 +213,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -226,7 +228,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -236,28 +238,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -291,7 +298,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -323,6 +330,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -338,7 +356,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
index a0d51421ee0..409d1ee542d 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
@@ -40,7 +40,9 @@ spec:
- --config-yaml test bootstrap config
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
- --concurrency 4
+ - --drain-time-s 60
command:
- envoy
env:
@@ -54,7 +56,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -64,28 +66,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -119,7 +126,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -151,6 +158,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -166,7 +184,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
index 7c64e500cb6..a9616129ff9 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -208,6 +208,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
- --key1 val1
- --key2 val2
command:
@@ -223,7 +225,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -233,28 +235,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -288,7 +295,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -320,6 +327,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -335,7 +353,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
index 8be6632a3bf..b3d3c8301e6 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -208,6 +208,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -221,7 +223,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -231,28 +233,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -286,7 +293,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -318,6 +325,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -336,7 +354,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
index 3847891f6ab..ac554d2f387 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -208,6 +208,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -221,7 +223,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -231,28 +233,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -286,7 +293,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -318,6 +325,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -333,7 +351,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
index 71b63d6b311..c51e2a86ec3 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -208,6 +208,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -221,7 +223,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -231,28 +233,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -286,7 +293,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -318,6 +325,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -336,7 +354,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
index 91b9e52d325..cf8ef7144a5 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -130,7 +130,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -153,13 +153,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -191,13 +191,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -208,6 +208,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -221,7 +223,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -231,28 +233,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -286,7 +293,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -318,6 +325,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -333,7 +351,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
topologySpreadConstraints:
- labelSelector:
matchLabels:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
index 6cb7499b104..b9d6973e3e5 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
@@ -44,6 +44,8 @@ spec:
- --config-yaml test bootstrap config
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -57,7 +59,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -67,28 +69,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -122,7 +129,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -154,6 +161,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -169,7 +187,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
index ff9605d9f18..30172b63ce8 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
@@ -44,7 +44,9 @@ spec:
- --config-yaml test bootstrap config
- --log-level error
- --cpuset-threads
+ - --drain-strategy immediate
- --component-log-level filter:info
+ - --drain-time-s 60
command:
- envoy
env:
@@ -58,7 +60,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -68,28 +70,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -123,7 +130,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -155,6 +162,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -170,7 +188,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
index 0434fb4cab4..a312bb39a61 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
@@ -19,7 +19,6 @@ spec:
app.kubernetes.io/component: proxy
app.kubernetes.io/managed-by: envoy-gateway
app.kubernetes.io/name: envoy
- foo.bar: custom-label
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
strategy:
@@ -81,7 +80,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -137,7 +136,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -160,13 +159,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -198,13 +197,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -230,6 +229,8 @@ spec:
value: 0.98
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -253,22 +254,16 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -313,7 +308,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -345,6 +340,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -362,7 +368,7 @@ spec:
securityContext:
runAsUser: 1000
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
index 89c92870887..e4518aa9be7 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
@@ -19,7 +19,6 @@ spec:
app.kubernetes.io/component: proxy
app.kubernetes.io/managed-by: envoy-gateway
app.kubernetes.io/name: envoy
- foo.bar: custom-label
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
strategy:
@@ -81,7 +80,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -137,7 +136,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -160,13 +159,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -198,13 +197,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -230,6 +229,8 @@ spec:
value: 0.98
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -253,22 +254,16 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -315,7 +310,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -347,6 +342,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -377,7 +383,7 @@ spec:
securityContext:
runAsUser: 1000
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
index c5e2d4ce3c1..5d34ac37081 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
@@ -79,7 +79,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -135,7 +135,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -158,13 +158,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -196,13 +196,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -228,6 +228,8 @@ spec:
value: 0.98
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -251,22 +253,16 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -311,7 +307,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -343,6 +339,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -360,7 +367,7 @@ spec:
securityContext:
runAsUser: 1000
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
index 9ef09dd6828..d257b62dd62 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
@@ -78,7 +78,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -134,7 +134,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -157,13 +157,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -195,13 +195,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -212,6 +212,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -225,7 +227,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -235,28 +237,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -290,7 +297,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -322,6 +329,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -337,7 +355,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
index cc33a09c7b3..c8a9d5b4240 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
@@ -74,7 +74,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -108,7 +108,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -131,13 +131,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -169,13 +169,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -186,6 +186,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -199,7 +201,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -208,26 +210,30 @@ spec:
port: 19002
scheme: HTTP
name: envoy
- ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -261,7 +267,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -293,6 +299,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -308,7 +325,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
new file mode 100644
index 00000000000..fe8d8f8ecfe
--- /dev/null
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
@@ -0,0 +1,375 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ creationTimestamp: null
+ labels:
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: envoy-default-37a8eec1
+ namespace: envoy-gateway-system
+spec:
+ progressDeadlineSeconds: 600
+ revisionHistoryLimit: 10
+ selector:
+ matchLabels:
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ annotations:
+ prometheus.io/path: /stats/prometheus
+ prometheus.io/port: "19001"
+ prometheus.io/scrape: "true"
+ creationTimestamp: null
+ labels:
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ spec:
+ automountServiceAccountToken: false
+ containers:
+ - args:
+ - --service-cluster default
+ - --service-node $(ENVOY_POD_NAME)
+ - |
+ --config-yaml admin:
+ access_log:
+ - name: envoy.access_loggers.file
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ path: /dev/null
+ address:
+ socket_address:
+ address: 127.0.0.1
+ port_value: 19000
+ layered_runtime:
+ layers:
+ - name: global_config
+ static_layer:
+ envoy.restart_features.use_eds_cache_for_ads: true
+ re2.max_program_size.error_level: 4294967295
+ re2.max_program_size.warn_level: 1000
+ dynamic_resources:
+ ads_config:
+ api_type: DELTA_GRPC
+ transport_api_version: V3
+ grpc_services:
+ - envoy_grpc:
+ cluster_name: xds_cluster
+ set_node_on_first_message_only: true
+ lds_config:
+ ads: {}
+ resource_api_version: V3
+ cds_config:
+ ads: {}
+ resource_api_version: V3
+ static_resources:
+ listeners:
+ - name: envoy-gateway-proxy-ready-::-19001
+ address:
+ socket_address:
+ address: '::'
+ port_value: 19001
+ protocol: TCP
+ ipv4_compat: true
+ filter_chains:
+ - filters:
+ - name: envoy.filters.network.http_connection_manager
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ stat_prefix: eg-ready-http
+ route_config:
+ name: local_route
+ virtual_hosts:
+ - name: prometheus_stats
+ domains:
+ - "*"
+ routes:
+ - match:
+ prefix: /stats/prometheus
+ route:
+ cluster: prometheus_stats
+ http_filters:
+ - name: envoy.filters.http.health_check
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck
+ pass_through_mode: false
+ headers:
+ - name: ":path"
+ string_match:
+ exact: /ready
+ - name: envoy.filters.http.router
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ clusters:
+ - name: prometheus_stats
+ connect_timeout: 0.250s
+ type: STATIC
+ lb_policy: ROUND_ROBIN
+ load_assignment:
+ cluster_name: prometheus_stats
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: 127.0.0.1
+ port_value: 19000
+ - connect_timeout: 10s
+ load_assignment:
+ cluster_name: xds_cluster
+ endpoints:
+ - load_balancing_weight: 1
+ lb_endpoints:
+ - load_balancing_weight: 1
+ endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+ port_value: 18000
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ explicit_http_config:
+ http2_protocol_options:
+ connection_keepalive:
+ interval: 30s
+ timeout: 5s
+ name: xds_cluster
+ type: STRICT_DNS
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+ - name: wasm_cluster
+ type: STRICT_DNS
+ connect_timeout: 10s
+ load_assignment:
+ cluster_name: wasm_cluster
+ endpoints:
+ - load_balancing_weight: 1
+ lb_endpoints:
+ - load_balancing_weight: 1
+ endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway
+ port_value: 18002
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ explicit_http_config:
+ http2_protocol_options: {}
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+ overload_manager:
+ refresh_interval: 0.25s
+ resource_monitors:
+ - name: "envoy.resource_monitors.global_downstream_max_connections"
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
+ max_active_downstream_connections: 50000
+ - --log-level warn
+ - --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
+ command:
+ - envoy
+ env:
+ - name: ENVOY_GATEWAY_NAMESPACE
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.namespace
+ - name: ENVOY_POD_NAME
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.name
+ image: docker.io/envoyproxy/envoy:distroless-dev
+ imagePullPolicy: IfNotPresent
+ lifecycle:
+ preStop:
+ httpGet:
+ path: /shutdown/ready
+ port: 19002
+ scheme: HTTP
+ name: envoy
+ ports:
+ - containerPort: 19001
+ name: metrics
+ protocol: TCP
+ readinessProbe:
+ failureThreshold: 1
+ httpGet:
+ path: /ready
+ port: 19001
+ scheme: HTTP
+ periodSeconds: 5
+ successThreshold: 1
+ timeoutSeconds: 1
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
+ startupProbe:
+ failureThreshold: 30
+ httpGet:
+ path: /ready
+ port: 19001
+ scheme: HTTP
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ volumeMounts:
+ - mountPath: /certs
+ name: certs
+ readOnly: true
+ - mountPath: /sds
+ name: sds
+ - args:
+ - envoy
+ - shutdown-manager
+ command:
+ - envoy-gateway
+ env:
+ - name: ENVOY_GATEWAY_NAMESPACE
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.namespace
+ - name: ENVOY_POD_NAME
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.name
+ image: docker.io/envoyproxy/gateway-dev:latest
+ imagePullPolicy: IfNotPresent
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - envoy-gateway
+ - envoy
+ - shutdown
+ livenessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /healthz
+ port: 19002
+ scheme: HTTP
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ name: shutdown-manager
+ readinessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /healthz
+ port: 19002
+ scheme: HTTP
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ resources:
+ requests:
+ cpu: 10m
+ memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
+ startupProbe:
+ failureThreshold: 30
+ httpGet:
+ path: /healthz
+ port: 19002
+ scheme: HTTP
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ dnsPolicy: ClusterFirst
+ restartPolicy: Always
+ schedulerName: default-scheduler
+ serviceAccountName: envoy-default-37a8eec1
+ terminationGracePeriodSeconds: 360
+ volumes:
+ - name: certs
+ secret:
+ defaultMode: 420
+ secretName: envoy
+ - configMap:
+ defaultMode: 420
+ items:
+ - key: xds-trusted-ca.json
+ path: xds-trusted-ca.json
+ - key: xds-certificate.json
+ path: xds-certificate.json
+ name: envoy-default-37a8eec1
+ optional: false
+ name: sds
+status: {}
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
index 4ff157e8cd8..232fa80b00f 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
@@ -79,7 +79,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -135,7 +135,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -158,13 +158,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -196,13 +196,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -228,6 +228,8 @@ spec:
value: 0.98
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -255,22 +257,16 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -315,7 +311,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -347,6 +343,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -364,7 +371,7 @@ spec:
securityContext:
runAsUser: 1000
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
new file mode 100644
index 00000000000..cde8a785717
--- /dev/null
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
@@ -0,0 +1,374 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ creationTimestamp: null
+ labels:
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: envoy-default-37a8eec1
+ namespace: envoy-gateway-system
+spec:
+ progressDeadlineSeconds: 600
+ revisionHistoryLimit: 10
+ selector:
+ matchLabels:
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ annotations:
+ prometheus.io/path: /stats/prometheus
+ prometheus.io/port: "19001"
+ prometheus.io/scrape: "true"
+ creationTimestamp: null
+ labels:
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ spec:
+ automountServiceAccountToken: false
+ containers:
+ - args:
+ - --service-cluster default
+ - --service-node $(ENVOY_POD_NAME)
+ - |
+ --config-yaml admin:
+ access_log:
+ - name: envoy.access_loggers.file
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ path: /dev/null
+ address:
+ socket_address:
+ address: ::1
+ port_value: 19000
+ layered_runtime:
+ layers:
+ - name: global_config
+ static_layer:
+ envoy.restart_features.use_eds_cache_for_ads: true
+ re2.max_program_size.error_level: 4294967295
+ re2.max_program_size.warn_level: 1000
+ dynamic_resources:
+ ads_config:
+ api_type: DELTA_GRPC
+ transport_api_version: V3
+ grpc_services:
+ - envoy_grpc:
+ cluster_name: xds_cluster
+ set_node_on_first_message_only: true
+ lds_config:
+ ads: {}
+ resource_api_version: V3
+ cds_config:
+ ads: {}
+ resource_api_version: V3
+ static_resources:
+ listeners:
+ - name: envoy-gateway-proxy-ready-::-19001
+ address:
+ socket_address:
+ address: '::'
+ port_value: 19001
+ protocol: TCP
+ filter_chains:
+ - filters:
+ - name: envoy.filters.network.http_connection_manager
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ stat_prefix: eg-ready-http
+ route_config:
+ name: local_route
+ virtual_hosts:
+ - name: prometheus_stats
+ domains:
+ - "*"
+ routes:
+ - match:
+ prefix: /stats/prometheus
+ route:
+ cluster: prometheus_stats
+ http_filters:
+ - name: envoy.filters.http.health_check
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck
+ pass_through_mode: false
+ headers:
+ - name: ":path"
+ string_match:
+ exact: /ready
+ - name: envoy.filters.http.router
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ clusters:
+ - name: prometheus_stats
+ connect_timeout: 0.250s
+ type: STATIC
+ lb_policy: ROUND_ROBIN
+ load_assignment:
+ cluster_name: prometheus_stats
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: ::1
+ port_value: 19000
+ - connect_timeout: 10s
+ load_assignment:
+ cluster_name: xds_cluster
+ endpoints:
+ - load_balancing_weight: 1
+ lb_endpoints:
+ - load_balancing_weight: 1
+ endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+ port_value: 18000
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ explicit_http_config:
+ http2_protocol_options:
+ connection_keepalive:
+ interval: 30s
+ timeout: 5s
+ name: xds_cluster
+ type: STRICT_DNS
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+ - name: wasm_cluster
+ type: STRICT_DNS
+ connect_timeout: 10s
+ load_assignment:
+ cluster_name: wasm_cluster
+ endpoints:
+ - load_balancing_weight: 1
+ lb_endpoints:
+ - load_balancing_weight: 1
+ endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway
+ port_value: 18002
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ explicit_http_config:
+ http2_protocol_options: {}
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+ overload_manager:
+ refresh_interval: 0.25s
+ resource_monitors:
+ - name: "envoy.resource_monitors.global_downstream_max_connections"
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
+ max_active_downstream_connections: 50000
+ - --log-level warn
+ - --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
+ command:
+ - envoy
+ env:
+ - name: ENVOY_GATEWAY_NAMESPACE
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.namespace
+ - name: ENVOY_POD_NAME
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.name
+ image: docker.io/envoyproxy/envoy:distroless-dev
+ imagePullPolicy: IfNotPresent
+ lifecycle:
+ preStop:
+ httpGet:
+ path: /shutdown/ready
+ port: 19002
+ scheme: HTTP
+ name: envoy
+ ports:
+ - containerPort: 19001
+ name: metrics
+ protocol: TCP
+ readinessProbe:
+ failureThreshold: 1
+ httpGet:
+ path: /ready
+ port: 19001
+ scheme: HTTP
+ periodSeconds: 5
+ successThreshold: 1
+ timeoutSeconds: 1
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
+ startupProbe:
+ failureThreshold: 30
+ httpGet:
+ path: /ready
+ port: 19001
+ scheme: HTTP
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ volumeMounts:
+ - mountPath: /certs
+ name: certs
+ readOnly: true
+ - mountPath: /sds
+ name: sds
+ - args:
+ - envoy
+ - shutdown-manager
+ command:
+ - envoy-gateway
+ env:
+ - name: ENVOY_GATEWAY_NAMESPACE
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.namespace
+ - name: ENVOY_POD_NAME
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.name
+ image: docker.io/envoyproxy/gateway-dev:latest
+ imagePullPolicy: IfNotPresent
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - envoy-gateway
+ - envoy
+ - shutdown
+ livenessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /healthz
+ port: 19002
+ scheme: HTTP
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ name: shutdown-manager
+ readinessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /healthz
+ port: 19002
+ scheme: HTTP
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ resources:
+ requests:
+ cpu: 10m
+ memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
+ startupProbe:
+ failureThreshold: 30
+ httpGet:
+ path: /healthz
+ port: 19002
+ scheme: HTTP
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ dnsPolicy: ClusterFirst
+ restartPolicy: Always
+ schedulerName: default-scheduler
+ serviceAccountName: envoy-default-37a8eec1
+ terminationGracePeriodSeconds: 360
+ volumes:
+ - name: certs
+ secret:
+ defaultMode: 420
+ secretName: envoy
+ - configMap:
+ defaultMode: 420
+ items:
+ - key: xds-trusted-ca.json
+ path: xds-trusted-ca.json
+ - key: xds-certificate.json
+ path: xds-certificate.json
+ name: envoy-default-37a8eec1
+ optional: false
+ name: sds
+status: {}
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
index 7137ea49d8c..3777fa8a88e 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
@@ -25,8 +25,6 @@ spec:
app.kubernetes.io/name: envoy
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
- label1: value1-override
- label2: value2
strategy:
type: RollingUpdate
template:
@@ -89,7 +87,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -145,7 +143,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -168,13 +166,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -206,13 +204,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -223,6 +221,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -236,7 +236,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -246,28 +246,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -301,7 +306,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -333,6 +338,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -348,7 +364,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
index 9d30812b114..e751dfc8cb1 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
@@ -78,7 +78,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -134,7 +134,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -157,13 +157,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -195,13 +195,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -212,6 +212,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -225,7 +227,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -235,28 +237,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -290,7 +297,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -322,6 +329,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -338,7 +356,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
index ddeaa935b97..53473970538 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
@@ -78,7 +78,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -134,7 +134,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -157,13 +157,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -195,13 +195,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -212,6 +212,7 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
- --drain-time-s 30
command:
- envoy
@@ -226,7 +227,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -236,28 +237,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -334,7 +340,16 @@ spec:
cpu: 100m
memory: 64Mi
securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
runAsUser: 1234
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
index ea54e6252d5..282e038d84b 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
@@ -79,7 +79,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -135,7 +135,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -158,13 +158,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -196,13 +196,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -228,6 +228,8 @@ spec:
value: 0.98
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -255,22 +257,16 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -315,7 +311,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -347,6 +343,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -364,7 +371,7 @@ spec:
securityContext:
runAsUser: 1000
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
index 95190921010..02c028e82e4 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
@@ -83,7 +83,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -139,7 +139,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -162,13 +162,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -200,13 +200,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -217,6 +217,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -230,7 +232,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -240,28 +242,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -295,7 +302,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -327,6 +334,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -342,7 +360,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
index 98706e847c6..16df5efe6a3 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
@@ -44,7 +44,9 @@ spec:
- --config-yaml test bootstrap config
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
- --concurrency 4
+ - --drain-time-s 60
command:
- envoy
env:
@@ -58,7 +60,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -68,28 +70,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -123,7 +130,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -155,6 +162,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -170,7 +188,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
index 038362e546b..b3275c38bcc 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
@@ -78,7 +78,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -134,7 +134,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -157,13 +157,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -195,13 +195,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -212,6 +212,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -225,7 +227,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -235,27 +237,32 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
limits:
cpu: 400m
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -289,7 +296,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -321,6 +328,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -336,7 +354,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
index 62816f17104..3a8ed4422e2 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
@@ -78,7 +78,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -134,7 +134,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -157,13 +157,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -195,13 +195,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -212,6 +212,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
- --key1 val1
- --key2 val2
command:
@@ -227,7 +229,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -237,28 +239,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -292,7 +299,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -324,6 +331,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -339,7 +357,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
index eb84fd39735..3759d793c85 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
@@ -78,7 +78,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -134,7 +134,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -157,13 +157,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -195,13 +195,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -212,6 +212,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -225,7 +227,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -235,28 +237,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -290,7 +297,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -322,6 +329,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -340,7 +358,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
index f212a6aa0ac..78bea6e40b0 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
@@ -78,7 +78,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -134,7 +134,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -157,13 +157,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -195,13 +195,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -212,6 +212,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -225,7 +227,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -235,28 +237,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -290,7 +297,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -322,6 +329,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -337,7 +355,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
index 6fbb69e7747..5afc2475eda 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
@@ -78,7 +78,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -134,7 +134,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -157,13 +157,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -195,13 +195,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -212,6 +212,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -225,7 +227,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -235,28 +237,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -290,7 +297,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -322,6 +329,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -340,7 +358,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
volumes:
- name: certs
secret:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
index 952b2ecf739..4dffb567e81 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
@@ -78,7 +78,7 @@ spec:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -134,7 +134,7 @@ spec:
endpoint:
address:
socket_address:
- address: envoy-gateway
+ address: envoy-gateway.envoy-gateway-system.svc.cluster.local
port_value: 18000
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -157,13 +157,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -195,13 +195,13 @@ spec:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
@@ -212,6 +212,8 @@ spec:
max_active_downstream_connections: 50000
- --log-level warn
- --cpuset-threads
+ - --drain-strategy immediate
+ - --drain-time-s 60
command:
- envoy
env:
@@ -225,7 +227,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-dev
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -235,28 +237,33 @@ spec:
scheme: HTTP
name: envoy
ports:
- - containerPort: 8080
- name: EnvoyHTTPPort
- protocol: TCP
- - containerPort: 8443
- name: EnvoyHTTPSPort
- protocol: TCP
- containerPort: 19001
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -290,7 +297,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- image: envoyproxy/gateway-dev:latest
+ image: docker.io/envoyproxy/gateway-dev:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -322,6 +329,17 @@ spec:
requests:
cpu: 10m
memory: 32Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ runAsGroup: 65532
+ runAsNonRoot: true
+ runAsUser: 65532
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -337,7 +355,7 @@ spec:
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-37a8eec1
- terminationGracePeriodSeconds: 900
+ terminationGracePeriodSeconds: 360
topologySpreadConstraints:
- labelSelector:
matchLabels:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/hpa/patch-json-hpa.yaml b/internal/infrastructure/kubernetes/proxy/testdata/hpa/patch-json-hpa.yaml
new file mode 100644
index 00000000000..38d3d474d81
--- /dev/null
+++ b/internal/infrastructure/kubernetes/proxy/testdata/hpa/patch-json-hpa.yaml
@@ -0,0 +1,21 @@
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: foo
+ namespace: envoy-gateway-system
+spec:
+ metrics:
+ - resource:
+ name: cpu
+ target:
+ averageUtilization: 80
+ type: Utilization
+ type: Resource
+ maxReplicas: 1
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: bar
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/hpa/patch-strategic-hpa.yaml b/internal/infrastructure/kubernetes/proxy/testdata/hpa/patch-strategic-hpa.yaml
new file mode 100644
index 00000000000..24a9f6f3a1d
--- /dev/null
+++ b/internal/infrastructure/kubernetes/proxy/testdata/hpa/patch-strategic-hpa.yaml
@@ -0,0 +1,21 @@
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: foo
+ namespace: envoy-gateway-system
+spec:
+ metrics:
+ - resource:
+ name: cpu
+ target:
+ averageUtilization: 50
+ type: Utilization
+ type: Resource
+ maxReplicas: 1
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: envoy-default-37a8eec1
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/pdb/patch-json-pdb.yaml b/internal/infrastructure/kubernetes/proxy/testdata/pdb/patch-json-pdb.yaml
new file mode 100644
index 00000000000..cc4aa473337
--- /dev/null
+++ b/internal/infrastructure/kubernetes/proxy/testdata/pdb/patch-json-pdb.yaml
@@ -0,0 +1,15 @@
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: foo
+ namespace: envoy-gateway-system
+spec:
+ minAvailable: 1
+ selector:
+ matchLabels:
+ app: bar
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/pdb/patch-strategic-pdb.yaml b/internal/infrastructure/kubernetes/proxy/testdata/pdb/patch-strategic-pdb.yaml
new file mode 100644
index 00000000000..20a25b7e1b0
--- /dev/null
+++ b/internal/infrastructure/kubernetes/proxy/testdata/pdb/patch-strategic-pdb.yaml
@@ -0,0 +1,10 @@
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: foo
+ namespace: envoy-gateway-system
+spec:
+ minAvailable: 1
+ selector:
+ matchLabels:
+ app: bar
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/services/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/services/custom.yaml
index e898ccb1aff..d087bf24bf6 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/services/custom.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/services/custom.yaml
@@ -4,6 +4,7 @@ metadata:
annotations:
key1: value1
labels:
+ key1: value1
app.kubernetes.io/name: envoy
app.kubernetes.io/component: proxy
app.kubernetes.io/managed-by: envoy-gateway
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/services/override-labels.yaml b/internal/infrastructure/kubernetes/proxy/testdata/services/override-labels.yaml
new file mode 100644
index 00000000000..6f60f58176c
--- /dev/null
+++ b/internal/infrastructure/kubernetes/proxy/testdata/services/override-labels.yaml
@@ -0,0 +1,37 @@
+apiVersion: v1
+kind: Service
+metadata:
+ annotations:
+ anno1: value1
+ anno2: value2
+ labels:
+ app.kubernetes.io/name: envoy
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ label1: value1-override
+ label2: value2
+ name: envoy-default-37a8eec1
+ namespace: envoy-gateway-system
+spec:
+ externalTrafficPolicy: Local
+ ports:
+ - name: EnvoyHTTPPort
+ port: 0
+ protocol: TCP
+ targetPort: 8080
+ - name: EnvoyHTTPSPort
+ port: 0
+ protocol: TCP
+ targetPort: 8443
+ selector:
+ app.kubernetes.io/name: envoy
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ label1: value1
+ label2: value2
+ sessionAffinity: None
+ type: LoadBalancer
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/services/with-svc-labels.yaml b/internal/infrastructure/kubernetes/proxy/testdata/services/with-svc-labels.yaml
new file mode 100644
index 00000000000..8ff9e5bb319
--- /dev/null
+++ b/internal/infrastructure/kubernetes/proxy/testdata/services/with-svc-labels.yaml
@@ -0,0 +1,32 @@
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ label1: value1
+ label2: value2
+ app.kubernetes.io/name: envoy
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: envoy-default-37a8eec1
+ namespace: envoy-gateway-system
+spec:
+ externalTrafficPolicy: Local
+ ports:
+ - name: EnvoyHTTPPort
+ port: 0
+ protocol: TCP
+ targetPort: 8080
+ - name: EnvoyHTTPSPort
+ port: 0
+ protocol: TCP
+ targetPort: 8443
+ selector:
+ app.kubernetes.io/name: envoy
+ app.kubernetes.io/component: proxy
+ app.kubernetes.io/managed-by: envoy-gateway
+ gateway.envoyproxy.io/owning-gateway-name: default
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ sessionAffinity: None
+ type: LoadBalancer
diff --git a/internal/infrastructure/kubernetes/proxy_configmap_test.go b/internal/infrastructure/kubernetes/proxy_configmap_test.go
index b16a0f61bbf..ec4c0ec74e7 100644
--- a/internal/infrastructure/kubernetes/proxy_configmap_test.go
+++ b/internal/infrastructure/kubernetes/proxy_configmap_test.go
@@ -20,6 +20,7 @@ import (
"github.com/envoyproxy/gateway/internal/envoygateway"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/infrastructure/common"
"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy"
"github.com/envoyproxy/gateway/internal/ir"
)
@@ -53,8 +54,8 @@ func TestCreateOrUpdateProxyConfigMap(t *testing.T) {
},
},
Data: map[string]string{
- proxy.SdsCAFilename: proxy.SdsCAConfigMapData,
- proxy.SdsCertFilename: proxy.SdsCertConfigMapData,
+ common.SdsCAFilename: common.GetSdsCAConfigMapData(proxy.XdsTLSCaFilepath),
+ common.SdsCertFilename: common.GetSdsCertConfigMapData(proxy.XdsTLSCertFilepath, proxy.XdsTLSKeyFilepath),
},
},
},
@@ -87,15 +88,14 @@ func TestCreateOrUpdateProxyConfigMap(t *testing.T) {
},
},
Data: map[string]string{
- proxy.SdsCAFilename: proxy.SdsCAConfigMapData,
- proxy.SdsCertFilename: proxy.SdsCertConfigMapData,
+ common.SdsCAFilename: common.GetSdsCAConfigMapData(proxy.XdsTLSCaFilepath),
+ common.SdsCertFilename: common.GetSdsCertConfigMapData(proxy.XdsTLSCertFilepath, proxy.XdsTLSKeyFilepath),
},
},
},
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var cli client.Client
if tc.current != nil {
@@ -111,7 +111,7 @@ func TestCreateOrUpdateProxyConfigMap(t *testing.T) {
Build()
}
kube := NewInfra(cli, cfg)
- r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra(), kube.EnvoyGateway)
+ r := proxy.NewResourceRender(kube.Namespace, kube.DNSDomain, infra.GetProxyInfra(), kube.EnvoyGateway)
err := kube.createOrUpdateConfigMap(context.Background(), r)
require.NoError(t, err)
actual := &corev1.ConfigMap{
@@ -162,7 +162,6 @@ func TestDeleteConfigProxyMap(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
cli := fakeclient.NewClientBuilder().WithScheme(envoygateway.GetScheme()).WithObjects(tc.current).Build()
kube := NewInfra(cli, cfg)
@@ -170,7 +169,7 @@ func TestDeleteConfigProxyMap(t *testing.T) {
infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default"
infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name
- r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra(), kube.EnvoyGateway)
+ r := proxy.NewResourceRender(kube.Namespace, kube.DNSDomain, infra.GetProxyInfra(), kube.EnvoyGateway)
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: kube.Namespace,
diff --git a/internal/infrastructure/kubernetes/proxy_daemonset_test.go b/internal/infrastructure/kubernetes/proxy_daemonset_test.go
new file mode 100644
index 00000000000..2c126586247
--- /dev/null
+++ b/internal/infrastructure/kubernetes/proxy_daemonset_test.go
@@ -0,0 +1,266 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package kubernetes
+
+import (
+ "context"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ appsv1 "k8s.io/api/apps/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/utils/ptr"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/envoygateway"
+ "github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy"
+ resource2 "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/resource"
+ "github.com/envoyproxy/gateway/internal/ir"
+)
+
+func daemonsetWithImage(ds *appsv1.DaemonSet, image string) *appsv1.DaemonSet {
+ dCopy := ds.DeepCopy()
+ for i, c := range dCopy.Spec.Template.Spec.Containers {
+ if c.Name == envoyContainerName {
+ dCopy.Spec.Template.Spec.Containers[i].Image = image
+ }
+ }
+ return dCopy
+}
+
+func daemonsetWithSelectorAndLabel(ds *appsv1.DaemonSet, selector *metav1.LabelSelector, additionalLabel map[string]string) *appsv1.DaemonSet {
+ dCopy := ds.DeepCopy()
+ if selector != nil {
+ dCopy.Spec.Selector = selector
+ }
+ for k, v := range additionalLabel {
+ dCopy.Spec.Template.Labels[k] = v
+ }
+ return dCopy
+}
+
+func TestCreateOrUpdateProxyDaemonSet(t *testing.T) {
+ cfg, err := config.New()
+ require.NoError(t, err)
+
+ infra := ir.NewInfra()
+ infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default"
+ infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name
+ infra.Proxy.Config = &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ // Use daemonset, instead of deployment.
+ EnvoyDaemonSet: egv1a1.DefaultKubernetesDaemonSet(egv1a1.DefaultEnvoyProxyImage),
+ EnvoyService: egv1a1.DefaultKubernetesService(),
+ },
+ },
+ },
+ }
+
+ r := proxy.NewResourceRender(cfg.Namespace, cfg.DNSDomain, infra.GetProxyInfra(), cfg.EnvoyGateway)
+ ds, err := r.DaemonSet()
+ require.NoError(t, err)
+
+ testCases := []struct {
+ name string
+ in *ir.Infra
+ current *appsv1.DaemonSet
+ want *appsv1.DaemonSet
+ wantErr bool
+ }{
+ {
+ name: "create daemonset",
+ in: infra,
+ want: ds,
+ },
+ {
+ name: "daemonset exists",
+ in: infra,
+ current: ds,
+ want: ds,
+ },
+ {
+ name: "update daemonset image",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{
+ Container: &egv1a1.KubernetesContainerSpec{
+ Image: ptr.To("envoyproxy/envoy-dev:v1.2.3"),
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: ds,
+ want: daemonsetWithImage(ds, "envoyproxy/envoy-dev:v1.2.3"),
+ },
+ {
+ name: "update daemonset label",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ // Add a new label to the custom label config.
+ // It wouldn't break the daemonset because the selector would still match after this label update.
+ "custom-label": "version1",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: ds,
+ // Selector is not updated with a custom label, only pod's label is updated.
+ want: daemonsetWithSelectorAndLabel(ds, nil, map[string]string{"custom-label": "version1"}),
+ },
+ {
+ name: "the daemonset originally has a selector and label, and an user add a new label to the custom label config",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ "custom-label": "version1",
+ "another-custom-label": "version1", // added.
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: daemonsetWithSelectorAndLabel(ds, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1"}),
+ // Only label is updated, selector is not updated.
+ want: daemonsetWithSelectorAndLabel(ds, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1", "another-custom-label": "version1"}),
+ },
+ {
+ name: "the daemonset originally has a selector and label, and an user update an existing custom label",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ // Update the label value which will break the daemonset
+ // because the selector cannot be updated while the user wants to update the label value.
+ // We cannot help this case, just emit an error and let the user recreate the envoy proxy by themselves.
+ "custom-label": "version2",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: daemonsetWithSelectorAndLabel(ds, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1"}),
+ wantErr: true,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ var cli client.Client
+ if tc.current != nil {
+ cli = fakeclient.NewClientBuilder().
+ WithScheme(envoygateway.GetScheme()).
+ WithObjects(tc.current).
+ WithInterceptorFuncs(interceptorFunc).
+ Build()
+ } else {
+ cli = fakeclient.NewClientBuilder().
+ WithScheme(envoygateway.GetScheme()).
+ WithInterceptorFuncs(interceptorFunc).
+ Build()
+ }
+
+ kube := NewInfra(cli, cfg)
+ r := proxy.NewResourceRender(kube.Namespace, kube.DNSDomain, tc.in.GetProxyInfra(), cfg.EnvoyGateway)
+ err := kube.createOrUpdateDaemonSet(context.Background(), r)
+ if tc.wantErr {
+ require.Error(t, err)
+ return
+ }
+ require.NoError(t, err)
+
+ actual := &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: kube.Namespace,
+ Name: proxy.ExpectedResourceHashedName(tc.in.Proxy.Name),
+ },
+ }
+ require.NoError(t, kube.Client.Get(context.Background(), client.ObjectKeyFromObject(actual), actual))
+ require.Equal(t, tc.want.Spec, actual.Spec)
+ })
+ }
+}
diff --git a/internal/infrastructure/kubernetes/proxy_deployment_test.go b/internal/infrastructure/kubernetes/proxy_deployment_test.go
index a1d595b750d..188c92961b3 100644
--- a/internal/infrastructure/kubernetes/proxy_deployment_test.go
+++ b/internal/infrastructure/kubernetes/proxy_deployment_test.go
@@ -21,6 +21,7 @@ import (
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/gatewayapi"
"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy"
+ resource2 "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/resource"
"github.com/envoyproxy/gateway/internal/ir"
)
@@ -39,6 +40,17 @@ func deploymentWithImage(deploy *appsv1.Deployment, image string) *appsv1.Deploy
return dCopy
}
+func deploymentWithSelectorAndLabel(deploy *appsv1.Deployment, selector *metav1.LabelSelector, additionalLabel map[string]string) *appsv1.Deployment {
+ dCopy := deploy.DeepCopy()
+ if selector != nil {
+ dCopy.Spec.Selector = selector
+ }
+ for k, v := range additionalLabel {
+ dCopy.Spec.Template.Labels[k] = v
+ }
+ return dCopy
+}
+
func TestCreateOrUpdateProxyDeployment(t *testing.T) {
cfg, err := config.New()
require.NoError(t, err)
@@ -47,7 +59,7 @@ func TestCreateOrUpdateProxyDeployment(t *testing.T) {
infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default"
infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name
- r := proxy.NewResourceRender(cfg.Namespace, infra.GetProxyInfra(), cfg.EnvoyGateway)
+ r := proxy.NewResourceRender(cfg.Namespace, cfg.DNSDomain, infra.GetProxyInfra(), cfg.EnvoyGateway)
deploy, err := r.Deployment()
require.NoError(t, err)
@@ -56,6 +68,7 @@ func TestCreateOrUpdateProxyDeployment(t *testing.T) {
in *ir.Infra
current *appsv1.Deployment
want *appsv1.Deployment
+ wantErr bool
}{
{
name: "create deployment",
@@ -99,10 +112,116 @@ func TestCreateOrUpdateProxyDeployment(t *testing.T) {
current: deploy,
want: deploymentWithImage(deploy, "envoyproxy/envoy-dev:v1.2.3"),
},
+ {
+ name: "update deployment label",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ "custom-label": "version1", // added.
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: deploy,
+ // Selector is not updated with a custom label, only pod's label is updated.
+ want: deploymentWithSelectorAndLabel(deploy, nil, map[string]string{"custom-label": "version1"}),
+ },
+ {
+ name: "the daemonset originally has a selector and label, and an user add a new label to the custom label config",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ "custom-label": "version1",
+ // Add a new label to the custom label config.
+ // It wouldn't break the deployment because the selector would still match after this label update.
+ "another-custom-label": "version1", // added.
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: deploymentWithSelectorAndLabel(deploy, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1"}),
+ // Only label is updated, selector is not updated.
+ want: deploymentWithSelectorAndLabel(deploy, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1", "another-custom-label": "version1"}),
+ },
+ {
+ name: "the deployment originally has a selector and label, and an user update an existing custom label",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ // Update the label value which will break the deployment
+ // because the selector cannot be updated while the user wants to update the label value.
+ // We cannot help this case, just emit an error and let the user recreate the envoy proxy by themselves.
+ "custom-label": "version2",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: deploymentWithSelectorAndLabel(deploy, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1"}),
+ wantErr: true,
+ },
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var cli client.Client
if tc.current != nil {
@@ -119,8 +238,12 @@ func TestCreateOrUpdateProxyDeployment(t *testing.T) {
}
kube := NewInfra(cli, cfg)
- r := proxy.NewResourceRender(kube.Namespace, tc.in.GetProxyInfra(), cfg.EnvoyGateway)
+ r := proxy.NewResourceRender(kube.Namespace, kube.DNSDomain, tc.in.GetProxyInfra(), cfg.EnvoyGateway)
err := kube.createOrUpdateDeployment(context.Background(), r)
+ if tc.wantErr {
+ require.Error(t, err)
+ return
+ }
require.NoError(t, err)
actual := &appsv1.Deployment{
@@ -155,14 +278,13 @@ func TestDeleteProxyDeployment(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
kube := NewInfra(cli, cfg)
infra := ir.NewInfra()
infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default"
infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name
- r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra(), kube.EnvoyGateway)
+ r := proxy.NewResourceRender(kube.Namespace, kube.DNSDomain, infra.GetProxyInfra(), kube.EnvoyGateway)
err := kube.createOrUpdateDeployment(context.Background(), r)
require.NoError(t, err)
diff --git a/internal/infrastructure/kubernetes/proxy_infra.go b/internal/infrastructure/kubernetes/proxy_infra.go
index e0b1fc5f9cc..b7d96f3bb3c 100644
--- a/internal/infrastructure/kubernetes/proxy_infra.go
+++ b/internal/infrastructure/kubernetes/proxy_infra.go
@@ -23,7 +23,7 @@ func (i *Infra) CreateOrUpdateProxyInfra(ctx context.Context, infra *ir.Infra) e
return errors.New("infra proxy ir is nil")
}
- r := proxy.NewResourceRender(i.Namespace, infra.GetProxyInfra(), i.EnvoyGateway)
+ r := proxy.NewResourceRender(i.Namespace, i.DNSDomain, infra.GetProxyInfra(), i.EnvoyGateway)
return i.createOrUpdate(ctx, r)
}
@@ -33,6 +33,6 @@ func (i *Infra) DeleteProxyInfra(ctx context.Context, infra *ir.Infra) error {
return errors.New("infra ir is nil")
}
- r := proxy.NewResourceRender(i.Namespace, infra.GetProxyInfra(), i.EnvoyGateway)
+ r := proxy.NewResourceRender(i.Namespace, i.DNSDomain, infra.GetProxyInfra(), i.EnvoyGateway)
return i.delete(ctx, r)
}
diff --git a/internal/infrastructure/kubernetes/proxy_infra_test.go b/internal/infrastructure/kubernetes/proxy_infra_test.go
index 5c8a8d34695..de0690e82c8 100644
--- a/internal/infrastructure/kubernetes/proxy_infra_test.go
+++ b/internal/infrastructure/kubernetes/proxy_infra_test.go
@@ -143,7 +143,6 @@ func TestCreateProxyInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
kube := newTestInfra(t)
@@ -210,7 +209,6 @@ func TestDeleteProxyInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
kube := newTestInfra(t)
diff --git a/internal/infrastructure/kubernetes/proxy_service_test.go b/internal/infrastructure/kubernetes/proxy_service_test.go
index 0c1c0cc6b89..dab16d5b981 100644
--- a/internal/infrastructure/kubernetes/proxy_service_test.go
+++ b/internal/infrastructure/kubernetes/proxy_service_test.go
@@ -26,14 +26,13 @@ func TestDeleteProxyService(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
kube := newTestInfra(t)
infra := ir.NewInfra()
infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default"
infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name
- r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra(), kube.EnvoyGateway)
+ r := proxy.NewResourceRender(kube.Namespace, kube.DNSDomain, infra.GetProxyInfra(), kube.EnvoyGateway)
err := kube.createOrUpdateService(context.Background(), r)
require.NoError(t, err)
diff --git a/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go b/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go
index 2b92fc53417..44732bf6b48 100644
--- a/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go
+++ b/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go
@@ -166,7 +166,6 @@ func TestCreateOrUpdateProxyServiceAccount(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
cfg, err := config.New()
require.NoError(t, err)
@@ -188,7 +187,7 @@ func TestCreateOrUpdateProxyServiceAccount(t *testing.T) {
kube := NewInfra(cli, cfg)
- r := proxy.NewResourceRender(kube.Namespace, tc.in.GetProxyInfra(), cfg.EnvoyGateway)
+ r := proxy.NewResourceRender(kube.Namespace, kube.DNSDomain, tc.in.GetProxyInfra(), cfg.EnvoyGateway)
err = kube.createOrUpdateServiceAccount(context.Background(), r)
require.NoError(t, err)
@@ -221,7 +220,7 @@ func TestDeleteProxyServiceAccount(t *testing.T) {
infra := ir.NewInfra()
infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default"
infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name
- r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra(), kube.EnvoyGateway)
+ r := proxy.NewResourceRender(kube.Namespace, kube.DNSDomain, infra.GetProxyInfra(), kube.EnvoyGateway)
err := kube.createOrUpdateServiceAccount(context.Background(), r)
require.NoError(t, err)
diff --git a/internal/infrastructure/kubernetes/ratelimit/resource.go b/internal/infrastructure/kubernetes/ratelimit/resource.go
index 9353b0ced00..4785a700d40 100644
--- a/internal/infrastructure/kubernetes/ratelimit/resource.go
+++ b/internal/infrastructure/kubernetes/ratelimit/resource.go
@@ -71,6 +71,8 @@ const (
LogLevelEnvVar = "LOG_LEVEL"
// UseStatsdEnvVar is the use statsd.
UseStatsdEnvVar = "USE_STATSD"
+ // StatsdPortEnvVar is the use statsd port.
+ StatsdPortEnvVar = "STATSD_PORT"
// ForceStartWithoutInitialConfigEnvVar enables start the ratelimit server without initial config.
ForceStartWithoutInitialConfigEnvVar = "FORCE_START_WITHOUT_INITIAL_CONFIG"
// ConfigTypeEnvVar is the configuration loading method for ratelimit.
@@ -158,7 +160,7 @@ func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeploymen
Env: expectedRateLimitContainerEnv(rateLimit, rateLimitDeployment, namespace),
Ports: ports,
Resources: *rateLimitDeployment.Container.Resources,
- SecurityContext: rateLimitDeployment.Container.SecurityContext,
+ SecurityContext: expectedRateLimitContainerSecurityContext(rateLimitDeployment),
VolumeMounts: expectedContainerVolumeMounts(rateLimit, rateLimitDeployment),
TerminationMessagePolicy: corev1.TerminationMessageReadFile,
TerminationMessagePath: "/dev/termination-log",
@@ -184,54 +186,16 @@ func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeploymen
},
},
TimeoutSeconds: 1,
- PeriodSeconds: 10,
+ PeriodSeconds: 5,
SuccessThreshold: 1,
- FailureThreshold: 3,
+ FailureThreshold: 1,
},
},
}
- if enablePrometheus(rateLimit) {
- containers = append(containers, promStatsdExporterContainer())
- }
-
return containers
}
-func promStatsdExporterContainer() corev1.Container {
- return corev1.Container{
- Name: "prom-statsd-exporter",
- Image: "prom/statsd-exporter:v0.18.0",
- ImagePullPolicy: corev1.PullIfNotPresent,
- Command: []string{
- "/bin/statsd_exporter",
- fmt.Sprintf("--web.listen-address=:%d", PrometheusPort),
- "--statsd.mapping-config=/etc/statsd-exporter/conf.yaml",
- },
- Ports: []corev1.ContainerPort{
- {
- Name: "statsd",
- ContainerPort: StatsdPort,
- Protocol: corev1.ProtocolTCP,
- },
- {
- Name: "metrics",
- ContainerPort: PrometheusPort,
- Protocol: corev1.ProtocolTCP,
- },
- },
- VolumeMounts: []corev1.VolumeMount{
- {
- Name: "statsd-exporter-config",
- ReadOnly: true,
- MountPath: "/etc/statsd-exporter",
- },
- },
- TerminationMessagePolicy: corev1.TerminationMessageReadFile,
- TerminationMessagePath: "/dev/termination-log",
- }
-}
-
// expectedContainerVolumeMounts returns expected rateLimit container volume mounts.
func expectedContainerVolumeMounts(rateLimit *egv1a1.RateLimit, rateLimitDeployment *egv1a1.KubernetesDeploymentSpec) []corev1.VolumeMount {
var volumeMounts []corev1.VolumeMount
@@ -243,6 +207,14 @@ func expectedContainerVolumeMounts(rateLimit *egv1a1.RateLimit, rateLimitDeploym
ReadOnly: true,
})
+ if enablePrometheus(rateLimit) {
+ volumeMounts = append(volumeMounts, corev1.VolumeMount{
+ Name: "statsd-exporter-config",
+ MountPath: "/etc/statsd-exporter",
+ ReadOnly: true,
+ })
+ }
+
if rateLimit.Backend.Redis.TLS != nil {
volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: "redis-certs",
@@ -412,6 +384,19 @@ func expectedRateLimitContainerEnv(rateLimit *egv1a1.RateLimit, rateLimitDeploym
}
}
+ if enablePrometheus(rateLimit) {
+ env = append(env, corev1.EnvVar{
+ Name: "USE_PROMETHEUS",
+ Value: "true",
+ }, corev1.EnvVar{
+ Name: "PROMETHEUS_ADDR",
+ Value: ":19001",
+ }, corev1.EnvVar{
+ Name: "PROMETHEUS_MAPPER_YAML",
+ Value: "/etc/statsd-exporter/conf.yaml",
+ })
+ }
+
if enableTracing(rateLimit) {
sampleRate := 1.0
if rateLimit.Telemetry.Tracing.SamplingRate != nil {
@@ -503,3 +488,18 @@ func checkTraceEndpointScheme(url string) string {
return fmt.Sprintf("%s%s", httpScheme, url)
}
+
+func expectedRateLimitContainerSecurityContext(rateLimitDeployment *egv1a1.KubernetesDeploymentSpec) *corev1.SecurityContext {
+ if rateLimitDeployment.Container.SecurityContext != nil {
+ return rateLimitDeployment.Container.SecurityContext
+ }
+ return defaultSecurityContext()
+}
+
+func defaultSecurityContext() *corev1.SecurityContext {
+ defaultSC := resource.DefaultSecurityContext()
+ // run as non-root user
+ defaultSC.RunAsGroup = ptr.To(int64(65534))
+ defaultSC.RunAsUser = ptr.To(int64(65534))
+ return defaultSC
+}
diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go
index 14d2a3d830b..3336d41eec2 100644
--- a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go
+++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go
@@ -9,11 +9,13 @@ import (
_ "embed"
"strconv"
+ "golang.org/x/exp/maps"
appsv1 "k8s.io/api/apps/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/ptr"
@@ -59,6 +61,10 @@ func (r *ResourceRender) Name() string {
return InfraName
}
+func (r *ResourceRender) LabelSelector() labels.Selector {
+ return labels.SelectorFromSet(rateLimitLabels())
+}
+
func enablePrometheus(rl *egv1a1.RateLimit) bool {
if rl != nil &&
rl.Telemetry != nil &&
@@ -183,22 +189,43 @@ func (r *ResourceRender) ServiceAccount() (*corev1.ServiceAccount, error) {
return sa, nil
}
+// DeploymentSpec returns the `Deployment` sets spec.
+func (r *ResourceRender) DeploymentSpec() (*egv1a1.KubernetesDeploymentSpec, error) {
+ return r.rateLimitDeployment, nil
+}
+
// Deployment returns the expected rate limit Deployment based on the provided infra.
func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
+ // If deployment config is nil,ignore Deployment.
+ if deploymentConfig, er := r.DeploymentSpec(); deploymentConfig == nil {
+ return nil, er
+ }
+
containers := expectedRateLimitContainers(r.rateLimit, r.rateLimitDeployment, r.Namespace)
- labels := rateLimitLabels()
- selector := resource.GetSelector(labels)
+ selector := resource.GetSelector(rateLimitLabels())
+
+ podLabels := rateLimitLabels()
+ if r.rateLimitDeployment.Pod.Labels != nil {
+ maps.Copy(podLabels, r.rateLimitDeployment.Pod.Labels)
+ // Copy overwrites values in the dest map if they exist in the src map https://pkg.go.dev/maps#Copy
+ // It's applied again with the rateLimitLabels that are used as deployment selector to ensure those are not overwritten by user input
+ maps.Copy(podLabels, rateLimitLabels())
+ }
- var annotations map[string]string
+ var podAnnotations map[string]string
if enablePrometheus(r.rateLimit) {
- annotations = map[string]string{
+ podAnnotations = map[string]string{
"prometheus.io/path": "/metrics",
"prometheus.io/port": strconv.Itoa(PrometheusPort),
"prometheus.io/scrape": "true",
}
}
if r.rateLimitDeployment.Pod.Annotations != nil {
- annotations = r.rateLimitDeployment.Pod.Annotations
+ if podAnnotations != nil {
+ maps.Copy(podAnnotations, r.rateLimitDeployment.Pod.Annotations)
+ } else {
+ podAnnotations = r.rateLimitDeployment.Pod.Annotations
+ }
}
deployment := &appsv1.Deployment{
@@ -208,8 +235,7 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
},
ObjectMeta: metav1.ObjectMeta{
Namespace: r.Namespace,
- Name: InfraName,
- Labels: labels,
+ Labels: rateLimitLabels(),
},
Spec: appsv1.DeploymentSpec{
Replicas: r.rateLimitDeployment.Replicas,
@@ -217,8 +243,8 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
Selector: selector,
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
- Labels: selector.MatchLabels,
- Annotations: annotations,
+ Labels: podLabels,
+ Annotations: podAnnotations,
},
Spec: corev1.PodSpec{
Containers: containers,
@@ -242,6 +268,13 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
},
}
+ // set name
+ if r.rateLimitDeployment.Name != nil {
+ deployment.ObjectMeta.Name = *r.rateLimitDeployment.Name
+ } else {
+ deployment.ObjectMeta.Name = r.Name()
+ }
+
if r.ownerReferenceUID != nil {
if uid, ok := r.ownerReferenceUID[ResourceKindDeployment]; ok {
deployment.OwnerReferences = []metav1.OwnerReference{
@@ -264,15 +297,30 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
return deployment, nil
}
+// DaemonSetSpec returns the `DaemonSet` sets spec.
+func (r *ResourceRender) DaemonSetSpec() (*egv1a1.KubernetesDaemonSetSpec, error) {
+ return nil, nil
+}
+
// TODO: implement this method
func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) {
return nil, nil
}
+// HorizontalPodAutoscalerSpec returns the `HorizontalPodAutoscaler` sets spec.
+func (r *ResourceRender) HorizontalPodAutoscalerSpec() (*egv1a1.KubernetesHorizontalPodAutoscalerSpec, error) {
+ return nil, nil
+}
+
func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPodAutoscaler, error) {
return nil, nil
}
+// PodDisruptionBudgetSpec returns the `PodDisruptionBudget` sets spec.
+func (r *ResourceRender) PodDisruptionBudgetSpec() (*egv1a1.KubernetesPodDisruptionBudgetSpec, error) {
+ return nil, nil
+}
+
func (r *ResourceRender) PodDisruptionBudget() (*policyv1.PodDisruptionBudget, error) {
return nil, nil
}
diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go
index 4ee3a144bd9..c7aa23f7943 100644
--- a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go
@@ -9,6 +9,7 @@ import (
"flag"
"fmt"
"os"
+ "strconv"
"testing"
"github.com/stretchr/testify/assert"
@@ -56,7 +57,6 @@ func TestRateLimitLabelSelector(t *testing.T) {
}
for _, tc := range cases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
got := LabelSelector()
require.ElementsMatch(t, tc.expected, got)
@@ -80,7 +80,6 @@ func TestRateLimitLabels(t *testing.T) {
}
for _, tc := range cases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
got := rateLimitLabels()
require.Equal(t, tc.expected, got)
@@ -680,6 +679,50 @@ func TestDeployment(t *testing.T) {
},
},
},
+ {
+ caseName: "merge-labels",
+ rateLimit: &egv1a1.RateLimit{
+ Backend: egv1a1.RateLimitDatabaseBackend{
+ Type: egv1a1.RedisBackendType,
+ Redis: &egv1a1.RateLimitRedisSettings{
+ URL: "redis.redis.svc:6379",
+ },
+ },
+ },
+ deploy: &egv1a1.KubernetesDeploymentSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ "app.kubernetes.io/name": InfraName,
+ "app.kubernetes.io/component": "ratelimit",
+ "app.kubernetes.io/managed-by": "envoy-gateway",
+ "key1": "value1",
+ "key2": "value2",
+ },
+ },
+ },
+ },
+ {
+ caseName: "merge-annotations",
+ rateLimit: &egv1a1.RateLimit{
+ Backend: egv1a1.RateLimitDatabaseBackend{
+ Type: egv1a1.RedisBackendType,
+ Redis: &egv1a1.RateLimitRedisSettings{
+ URL: "redis.redis.svc:6379",
+ },
+ },
+ },
+ deploy: &egv1a1.KubernetesDeploymentSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Annotations: map[string]string{
+ "prometheus.io/path": "/metrics",
+ "prometheus.io/port": strconv.Itoa(PrometheusPort),
+ "prometheus.io/scrape": "true",
+ "key1": "value1",
+ "key2": "value2",
+ },
+ },
+ },
+ },
}
for _, tc := range cases {
t.Run(tc.caseName, func(t *testing.T) {
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml
index bfd2c28cc6a..0c1be549e83 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml
@@ -27,6 +27,8 @@ spec:
template:
metadata:
annotations:
+ prometheus.io/path: /metrics
+ prometheus.io/port: "19001"
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
@@ -79,6 +81,12 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
image: custom-image
imagePullPolicy: IfNotPresent
name: envoy-ratelimit
@@ -87,12 +95,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -119,24 +127,6 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml
index bfd2c28cc6a..0c1be549e83 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml
@@ -27,6 +27,8 @@ spec:
template:
metadata:
annotations:
+ prometheus.io/path: /metrics
+ prometheus.io/port: "19001"
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
@@ -79,6 +81,12 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
image: custom-image
imagePullPolicy: IfNotPresent
name: envoy-ratelimit
@@ -87,12 +95,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -119,24 +127,6 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
index db3b88ebaea..f3b49afb414 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
@@ -80,7 +80,13 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
- image: envoyproxy/ratelimit:master
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
+ image: docker.io/envoyproxy/ratelimit:master
imagePullPolicy: IfNotPresent
name: envoy-ratelimit
ports:
@@ -88,18 +94,30 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65534
+ runAsNonRoot: true
+ runAsUser: 65534
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -115,24 +133,6 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
index 091fe6edb38..b579400b05a 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
@@ -76,7 +76,7 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
- image: envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:master
imagePullPolicy: IfNotPresent
name: envoy-ratelimit
ports:
@@ -84,18 +84,30 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65534
+ runAsNonRoot: true
+ runAsUser: 65534
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
index 33d976d7766..c8586388f37 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
@@ -80,6 +80,12 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
- name: TRACING_ENABLED
value: "true"
- name: TRACING_SERVICE_NAME
@@ -95,7 +101,7 @@ spec:
value: "0.6"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://trace-collector.envoy-gateway-system.svc.cluster.local:4317
- image: envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:master
imagePullPolicy: IfNotPresent
name: envoy-ratelimit
ports:
@@ -103,18 +109,30 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65534
+ runAsNonRoot: true
+ runAsUser: 65534
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -130,24 +148,6 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
index 02ea3143bf6..002ee53bda6 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
@@ -80,6 +80,12 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
- name: TRACING_ENABLED
value: "true"
- name: TRACING_SERVICE_NAME
@@ -95,7 +101,7 @@ spec:
value: "1.0"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://trace-collector.envoy-gateway-system.svc.cluster.local:4318
- image: envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:master
imagePullPolicy: IfNotPresent
name: envoy-ratelimit
ports:
@@ -103,18 +109,30 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65534
+ runAsNonRoot: true
+ runAsUser: 65534
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -130,24 +148,6 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml
index 95516ce6c46..65c68972f9d 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml
@@ -27,6 +27,8 @@ spec:
template:
metadata:
annotations:
+ prometheus.io/path: /metrics
+ prometheus.io/port: "19001"
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
@@ -79,6 +81,12 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
- name: env_a
value: env_a_value
- name: env_b
@@ -91,12 +99,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -123,24 +131,6 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml
new file mode 100644
index 00000000000..fc6600de072
--- /dev/null
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml
@@ -0,0 +1,156 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ creationTimestamp: null
+ labels:
+ app.kubernetes.io/component: ratelimit
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy-ratelimit
+ name: envoy-ratelimit
+ namespace: envoy-gateway-system
+ ownerReferences:
+ - apiVersion: apps/v1
+ kind: Deployment
+ name: envoy-gateway
+ uid: test-owner-reference-uid-for-deployment
+spec:
+ progressDeadlineSeconds: 600
+ revisionHistoryLimit: 10
+ selector:
+ matchLabels:
+ app.kubernetes.io/component: ratelimit
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy-ratelimit
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ annotations:
+ key1: value1
+ key2: value2
+ prometheus.io/path: /metrics
+ prometheus.io/port: "19001"
+ prometheus.io/scrape: "true"
+ creationTimestamp: null
+ labels:
+ app.kubernetes.io/component: ratelimit
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy-ratelimit
+ spec:
+ automountServiceAccountToken: false
+ containers:
+ - command:
+ - /bin/ratelimit
+ env:
+ - name: RUNTIME_ROOT
+ value: /data
+ - name: RUNTIME_SUBDIRECTORY
+ value: ratelimit
+ - name: RUNTIME_IGNOREDOTFILES
+ value: "true"
+ - name: RUNTIME_WATCH_ROOT
+ value: "false"
+ - name: LOG_LEVEL
+ value: info
+ - name: USE_STATSD
+ value: "false"
+ - name: CONFIG_TYPE
+ value: GRPC_XDS_SOTW
+ - name: CONFIG_GRPC_XDS_SERVER_URL
+ value: envoy-gateway:18001
+ - name: CONFIG_GRPC_XDS_NODE_ID
+ value: envoy-ratelimit
+ - name: GRPC_SERVER_USE_TLS
+ value: "true"
+ - name: GRPC_SERVER_TLS_CERT
+ value: /certs/tls.crt
+ - name: GRPC_SERVER_TLS_KEY
+ value: /certs/tls.key
+ - name: GRPC_SERVER_TLS_CA_CERT
+ value: /certs/ca.crt
+ - name: CONFIG_GRPC_XDS_SERVER_USE_TLS
+ value: "true"
+ - name: CONFIG_GRPC_XDS_CLIENT_TLS_CERT
+ value: /certs/tls.crt
+ - name: CONFIG_GRPC_XDS_CLIENT_TLS_KEY
+ value: /certs/tls.key
+ - name: CONFIG_GRPC_XDS_SERVER_TLS_CACERT
+ value: /certs/ca.crt
+ - name: FORCE_START_WITHOUT_INITIAL_CONFIG
+ value: "true"
+ - name: REDIS_SOCKET_TYPE
+ value: tcp
+ - name: REDIS_URL
+ value: redis.redis.svc:6379
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
+ image: docker.io/envoyproxy/ratelimit:master
+ imagePullPolicy: IfNotPresent
+ name: envoy-ratelimit
+ ports:
+ - containerPort: 8081
+ name: grpc
+ protocol: TCP
+ readinessProbe:
+ failureThreshold: 1
+ httpGet:
+ path: /healthcheck
+ port: 8080
+ scheme: HTTP
+ periodSeconds: 5
+ successThreshold: 1
+ timeoutSeconds: 1
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65534
+ runAsNonRoot: true
+ runAsUser: 65534
+ seccompProfile:
+ type: RuntimeDefault
+ startupProbe:
+ failureThreshold: 30
+ httpGet:
+ path: /healthcheck
+ port: 8080
+ scheme: HTTP
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ volumeMounts:
+ - mountPath: /certs
+ name: certs
+ readOnly: true
+ - mountPath: /etc/statsd-exporter
+ name: statsd-exporter-config
+ readOnly: true
+ dnsPolicy: ClusterFirst
+ restartPolicy: Always
+ schedulerName: default-scheduler
+ serviceAccountName: envoy-ratelimit
+ terminationGracePeriodSeconds: 300
+ volumes:
+ - name: certs
+ secret:
+ defaultMode: 420
+ secretName: envoy-rate-limit
+ - configMap:
+ defaultMode: 420
+ name: statsd-exporter-config
+ optional: true
+ name: statsd-exporter-config
+status: {}
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml
new file mode 100644
index 00000000000..0c944d8fd82
--- /dev/null
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml
@@ -0,0 +1,156 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ creationTimestamp: null
+ labels:
+ app.kubernetes.io/component: ratelimit
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy-ratelimit
+ name: envoy-ratelimit
+ namespace: envoy-gateway-system
+ ownerReferences:
+ - apiVersion: apps/v1
+ kind: Deployment
+ name: envoy-gateway
+ uid: test-owner-reference-uid-for-deployment
+spec:
+ progressDeadlineSeconds: 600
+ revisionHistoryLimit: 10
+ selector:
+ matchLabels:
+ app.kubernetes.io/component: ratelimit
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy-ratelimit
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ annotations:
+ prometheus.io/path: /metrics
+ prometheus.io/port: "19001"
+ prometheus.io/scrape: "true"
+ creationTimestamp: null
+ labels:
+ app.kubernetes.io/component: ratelimit
+ app.kubernetes.io/managed-by: envoy-gateway
+ app.kubernetes.io/name: envoy-ratelimit
+ key1: value1
+ key2: value2
+ spec:
+ automountServiceAccountToken: false
+ containers:
+ - command:
+ - /bin/ratelimit
+ env:
+ - name: RUNTIME_ROOT
+ value: /data
+ - name: RUNTIME_SUBDIRECTORY
+ value: ratelimit
+ - name: RUNTIME_IGNOREDOTFILES
+ value: "true"
+ - name: RUNTIME_WATCH_ROOT
+ value: "false"
+ - name: LOG_LEVEL
+ value: info
+ - name: USE_STATSD
+ value: "false"
+ - name: CONFIG_TYPE
+ value: GRPC_XDS_SOTW
+ - name: CONFIG_GRPC_XDS_SERVER_URL
+ value: envoy-gateway:18001
+ - name: CONFIG_GRPC_XDS_NODE_ID
+ value: envoy-ratelimit
+ - name: GRPC_SERVER_USE_TLS
+ value: "true"
+ - name: GRPC_SERVER_TLS_CERT
+ value: /certs/tls.crt
+ - name: GRPC_SERVER_TLS_KEY
+ value: /certs/tls.key
+ - name: GRPC_SERVER_TLS_CA_CERT
+ value: /certs/ca.crt
+ - name: CONFIG_GRPC_XDS_SERVER_USE_TLS
+ value: "true"
+ - name: CONFIG_GRPC_XDS_CLIENT_TLS_CERT
+ value: /certs/tls.crt
+ - name: CONFIG_GRPC_XDS_CLIENT_TLS_KEY
+ value: /certs/tls.key
+ - name: CONFIG_GRPC_XDS_SERVER_TLS_CACERT
+ value: /certs/ca.crt
+ - name: FORCE_START_WITHOUT_INITIAL_CONFIG
+ value: "true"
+ - name: REDIS_SOCKET_TYPE
+ value: tcp
+ - name: REDIS_URL
+ value: redis.redis.svc:6379
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
+ image: docker.io/envoyproxy/ratelimit:master
+ imagePullPolicy: IfNotPresent
+ name: envoy-ratelimit
+ ports:
+ - containerPort: 8081
+ name: grpc
+ protocol: TCP
+ readinessProbe:
+ failureThreshold: 1
+ httpGet:
+ path: /healthcheck
+ port: 8080
+ scheme: HTTP
+ periodSeconds: 5
+ successThreshold: 1
+ timeoutSeconds: 1
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65534
+ runAsNonRoot: true
+ runAsUser: 65534
+ seccompProfile:
+ type: RuntimeDefault
+ startupProbe:
+ failureThreshold: 30
+ httpGet:
+ path: /healthcheck
+ port: 8080
+ scheme: HTTP
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ volumeMounts:
+ - mountPath: /certs
+ name: certs
+ readOnly: true
+ - mountPath: /etc/statsd-exporter
+ name: statsd-exporter-config
+ readOnly: true
+ dnsPolicy: ClusterFirst
+ restartPolicy: Always
+ schedulerName: default-scheduler
+ serviceAccountName: envoy-ratelimit
+ terminationGracePeriodSeconds: 300
+ volumes:
+ - name: certs
+ secret:
+ defaultMode: 420
+ secretName: envoy-rate-limit
+ - configMap:
+ defaultMode: 420
+ name: statsd-exporter-config
+ optional: true
+ name: statsd-exporter-config
+status: {}
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml
index 8a9cfb60c97..0c0f73f3c83 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml
@@ -27,6 +27,8 @@ spec:
template:
metadata:
annotations:
+ prometheus.io/path: /metrics
+ prometheus.io/port: "19001"
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
@@ -79,6 +81,12 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
image: custom-image
imagePullPolicy: IfNotPresent
name: envoy-ratelimit
@@ -87,12 +95,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -119,24 +127,6 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
index 971f019dd8d..5556e12d2ee 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
@@ -80,7 +80,13 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
- image: envoyproxy/ratelimit:master
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
+ image: docker.io/envoyproxy/ratelimit:master
imagePullPolicy: IfNotPresent
name: envoy-ratelimit
ports:
@@ -88,18 +94,30 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65534
+ runAsNonRoot: true
+ runAsUser: 65534
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -115,24 +133,6 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml
index 9854f37f4e2..29428fc447b 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml
@@ -27,6 +27,8 @@ spec:
template:
metadata:
annotations:
+ prometheus.io/path: /metrics
+ prometheus.io/port: "19001"
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
@@ -85,6 +87,12 @@ spec:
value: /redis-certs/tls.crt
- name: REDIS_TLS_CLIENT_KEY
value: /redis-certs/tls.key
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
- name: REDIS_AUTH
value: redis_auth_password
image: custom-image
@@ -95,12 +103,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -127,30 +135,12 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - mountPath: /redis-certs
- name: redis-certs
- readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
+ - mountPath: /redis-certs
+ name: redis-certs
+ readOnly: true
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml
index 56fdb156dcf..a2478222625 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml
@@ -27,6 +27,8 @@ spec:
template:
metadata:
annotations:
+ prometheus.io/path: /metrics
+ prometheus.io/port: "19001"
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
@@ -85,6 +87,12 @@ spec:
value: /redis-certs/tls.crt
- name: REDIS_TLS_CLIENT_KEY
value: /redis-certs/tls.key
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
- name: REDIS_AUTH
value: redis_auth_password
image: custom-image
@@ -95,12 +103,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -127,30 +135,12 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - mountPath: /redis-certs
- name: redis-certs
- readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
+ - mountPath: /redis-certs
+ name: redis-certs
+ readOnly: true
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml
index 01e779e9e49..30d8852d642 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml
@@ -27,6 +27,8 @@ spec:
template:
metadata:
annotations:
+ prometheus.io/path: /metrics
+ prometheus.io/port: "19001"
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
@@ -85,6 +87,12 @@ spec:
value: /redis-certs/tls.crt
- name: REDIS_TLS_CLIENT_KEY
value: /redis-certs/tls.key
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
- name: REDIS_AUTH
value: redis_auth_password
image: custom-image
@@ -95,12 +103,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
@@ -127,30 +135,12 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - mountPath: /redis-certs
- name: redis-certs
- readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
+ - mountPath: /redis-certs
+ name: redis-certs
+ readOnly: true
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
index b0325b6d835..f65e6f23e18 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
@@ -80,7 +80,13 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
- image: envoyproxy/ratelimit:master
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
+ image: docker.io/envoyproxy/ratelimit:master
imagePullPolicy: IfNotPresent
name: envoy-ratelimit
ports:
@@ -88,18 +94,30 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65534
+ runAsNonRoot: true
+ runAsUser: 65534
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -115,24 +133,6 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml
index 7ad968464b7..e726269ccbe 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml
@@ -80,7 +80,13 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
- image: envoyproxy/ratelimit:master
+ - name: USE_PROMETHEUS
+ value: "true"
+ - name: PROMETHEUS_ADDR
+ value: :19001
+ - name: PROMETHEUS_MAPPER_YAML
+ value: /etc/statsd-exporter/conf.yaml
+ image: docker.io/envoyproxy/ratelimit:master
imagePullPolicy: IfNotPresent
name: envoy-ratelimit
ports:
@@ -88,18 +94,30 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ privileged: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65534
+ runAsNonRoot: true
+ runAsUser: 65534
+ seccompProfile:
+ type: RuntimeDefault
startupProbe:
failureThreshold: 30
httpGet:
@@ -115,24 +133,6 @@ spec:
- mountPath: /certs
name: certs
readOnly: true
- - command:
- - /bin/statsd_exporter
- - --web.listen-address=:19001
- - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml
- image: prom/statsd-exporter:v0.18.0
- imagePullPolicy: IfNotPresent
- name: prom-statsd-exporter
- ports:
- - containerPort: 9125
- name: statsd
- protocol: TCP
- - containerPort: 19001
- name: metrics
- protocol: TCP
- resources: {}
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- mountPath: /etc/statsd-exporter
name: statsd-exporter-config
readOnly: true
diff --git a/internal/infrastructure/kubernetes/ratelimit_deployment_test.go b/internal/infrastructure/kubernetes/ratelimit_deployment_test.go
index d57e003d383..ea0e5017fd3 100644
--- a/internal/infrastructure/kubernetes/ratelimit_deployment_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit_deployment_test.go
@@ -64,7 +64,6 @@ func TestCreateOrUpdateRateLimitDeployment(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var cli client.Client
if tc.current != nil {
@@ -120,7 +119,6 @@ func TestDeleteRateLimitDeployment(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
kube := newTestInfra(t)
kube.EnvoyGateway.RateLimit = rl
diff --git a/internal/infrastructure/kubernetes/ratelimit_infra.go b/internal/infrastructure/kubernetes/ratelimit_infra.go
index 514f86a1d9d..d4f5707538c 100644
--- a/internal/infrastructure/kubernetes/ratelimit_infra.go
+++ b/internal/infrastructure/kubernetes/ratelimit_infra.go
@@ -52,10 +52,6 @@ func (i *Infra) CreateOrUpdateRateLimitInfra(ctx context.Context) error {
// DeleteRateLimitInfra removes the managed kube infra, if it doesn't exist.
func (i *Infra) DeleteRateLimitInfra(ctx context.Context) error {
- if err := ratelimit.Validate(ctx, i.Client.Client, i.EnvoyGateway, i.Namespace); err != nil {
- return err
- }
-
// Delete ratelimit infra do not require the uid of owner reference.
r := ratelimit.NewResourceRender(i.Namespace, i.EnvoyGateway, nil)
return i.delete(ctx, r)
diff --git a/internal/infrastructure/kubernetes/ratelimit_infra_test.go b/internal/infrastructure/kubernetes/ratelimit_infra_test.go
index a5934b12086..1b4976ac361 100644
--- a/internal/infrastructure/kubernetes/ratelimit_infra_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit_infra_test.go
@@ -127,7 +127,6 @@ func TestCreateRateLimitInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
kube := newTestInfra(t)
@@ -193,7 +192,6 @@ func TestDeleteRateLimitInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
kube := newTestInfra(t)
diff --git a/internal/infrastructure/kubernetes/ratelimit_service_test.go b/internal/infrastructure/kubernetes/ratelimit_service_test.go
index d117d9d57bf..db6578e2a31 100644
--- a/internal/infrastructure/kubernetes/ratelimit_service_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit_service_test.go
@@ -34,7 +34,6 @@ func TestDeleteRateLimitService(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
kube := newTestInfra(t)
diff --git a/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go b/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go
index 53084f6620d..630fa2e330a 100644
--- a/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go
@@ -88,7 +88,6 @@ func TestCreateOrUpdateRateLimitServiceAccount(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var cli client.Client
if tc.current != nil {
diff --git a/internal/infrastructure/kubernetes/resource/resource.go b/internal/infrastructure/kubernetes/resource/resource.go
index cff49336c71..dcbbadadb40 100644
--- a/internal/infrastructure/kubernetes/resource/resource.go
+++ b/internal/infrastructure/kubernetes/resource/resource.go
@@ -10,6 +10,7 @@ import (
"github.com/google/go-cmp/cmp/cmpopts"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/utils/ptr"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
)
@@ -37,7 +38,7 @@ func ExpectedServiceSpec(service *egv1a1.KubernetesServiceSpec) corev1.ServiceSp
if service.AllocateLoadBalancerNodePorts != nil {
serviceSpec.AllocateLoadBalancerNodePorts = service.AllocateLoadBalancerNodePorts
}
- if service.LoadBalancerSourceRanges != nil && len(service.LoadBalancerSourceRanges) > 0 {
+ if len(service.LoadBalancerSourceRanges) > 0 {
serviceSpec.LoadBalancerSourceRanges = service.LoadBalancerSourceRanges
}
if service.LoadBalancerIP != nil {
@@ -115,3 +116,21 @@ func ExpectedContainerVolumeMounts(container *egv1a1.KubernetesContainerSpec, vo
return volumeMounts
}
+
+// DefaultSecurityContext returns a default security context with minimal privileges.
+func DefaultSecurityContext() *corev1.SecurityContext {
+ return &corev1.SecurityContext{
+ AllowPrivilegeEscalation: ptr.To(false),
+ Capabilities: &corev1.Capabilities{
+ Drop: []corev1.Capability{
+ "ALL",
+ },
+ },
+ Privileged: ptr.To(false),
+ ReadOnlyRootFilesystem: ptr.To(true),
+ RunAsNonRoot: ptr.To(true),
+ SeccompProfile: &corev1.SeccompProfile{
+ Type: "RuntimeDefault",
+ },
+ }
+}
diff --git a/internal/infrastructure/kubernetes/resource/resource_test.go b/internal/infrastructure/kubernetes/resource/resource_test.go
index b65549911c7..52c1d73f6da 100644
--- a/internal/infrastructure/kubernetes/resource/resource_test.go
+++ b/internal/infrastructure/kubernetes/resource/resource_test.go
@@ -156,7 +156,6 @@ func TestGetSelector(t *testing.T) {
}
for _, tc := range cases {
- tc := tc
t.Run("", func(t *testing.T) {
got := GetSelector(tc.in)
require.Equal(t, tc.expected, got.MatchLabels)
diff --git a/internal/infrastructure/manager.go b/internal/infrastructure/manager.go
index 34fc1b24b12..0254eb1853b 100644
--- a/internal/infrastructure/manager.go
+++ b/internal/infrastructure/manager.go
@@ -15,11 +15,16 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/infrastructure/host"
"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes"
"github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/logging"
)
-var _ Manager = (*kubernetes.Infra)(nil)
+var (
+ _ Manager = (*kubernetes.Infra)(nil)
+ _ Manager = (*host.Infra)(nil)
+)
// Manager provides the scaffolding for managing infrastructure.
type Manager interface {
@@ -34,18 +39,34 @@ type Manager interface {
}
// NewManager returns a new infrastructure Manager.
-func NewManager(cfg *config.Server) (Manager, error) {
- var mgr Manager
- if cfg.EnvoyGateway.Provider.Type == egv1a1.ProviderTypeKubernetes {
- cli, err := client.New(clicfg.GetConfigOrDie(), client.Options{Scheme: envoygateway.GetScheme()})
- if err != nil {
- return nil, err
- }
- mgr = kubernetes.NewInfra(cli, cfg)
- } else {
- // Kube is the only supported provider type for now.
- return nil, fmt.Errorf("unsupported provider type %v", cfg.EnvoyGateway.Provider.Type)
+func NewManager(ctx context.Context, cfg *config.Server, logger logging.Logger) (mgr Manager, err error) {
+ switch cfg.EnvoyGateway.Provider.Type {
+ case egv1a1.ProviderTypeKubernetes:
+ mgr, err = newManagerForKubernetes(cfg)
+ case egv1a1.ProviderTypeCustom:
+ mgr, err = newManagerForCustom(ctx, cfg, logger)
}
+ if err != nil {
+ return nil, err
+ }
return mgr, nil
}
+
+func newManagerForKubernetes(cfg *config.Server) (Manager, error) {
+ cli, err := client.New(clicfg.GetConfigOrDie(), client.Options{Scheme: envoygateway.GetScheme()})
+ if err != nil {
+ return nil, err
+ }
+ return kubernetes.NewInfra(cli, cfg), nil
+}
+
+func newManagerForCustom(ctx context.Context, cfg *config.Server, logger logging.Logger) (Manager, error) {
+ infra := cfg.EnvoyGateway.Provider.Custom.Infrastructure
+ switch infra.Type {
+ case egv1a1.InfrastructureProviderTypeHost:
+ return host.NewInfra(ctx, cfg, logger)
+ default:
+ return nil, fmt.Errorf("unsupported provider type: %s", infra.Type)
+ }
+}
diff --git a/internal/infrastructure/runner/runner.go b/internal/infrastructure/runner/runner.go
index 7574c493090..3344ca0d349 100644
--- a/internal/infrastructure/runner/runner.go
+++ b/internal/infrastructure/runner/runner.go
@@ -38,7 +38,13 @@ func New(cfg *Config) *Runner {
// Start starts the infrastructure runner
func (r *Runner) Start(ctx context.Context) (err error) {
r.Logger = r.Logger.WithName(r.Name()).WithValues("runner", r.Name())
- r.mgr, err = infrastructure.NewManager(&r.Config.Server)
+ if r.EnvoyGateway.Provider.Type == egv1a1.ProviderTypeCustom &&
+ r.EnvoyGateway.Provider.Custom.Infrastructure == nil {
+ r.Logger.Info("provider is not specified, no infrastructure is available")
+ return nil
+ }
+
+ r.mgr, err = infrastructure.NewManager(ctx, &r.Config.Server, r.Logger)
if err != nil {
r.Logger.Error(err, "failed to create new manager")
return err
@@ -50,20 +56,24 @@ func (r *Runner) Start(ctx context.Context) (err error) {
// Enable global ratelimit if it has been configured.
if r.EnvoyGateway.RateLimit != nil {
go r.enableRateLimitInfra(ctx)
+ } else {
+ // Delete the ratelimit infra if it exists.
+ go func() {
+ if err := r.mgr.DeleteRateLimitInfra(ctx); err != nil {
+ r.Logger.Error(err, "failed to delete ratelimit infra")
+ }
+ }()
}
r.Logger.Info("started")
}
// When leader election is active, infrastructure initialization occurs only upon acquiring leadership
// to avoid multiple EG instances processing envoy proxy infra resources.
- if !ptr.Deref(r.EnvoyGateway.Provider.Kubernetes.LeaderElection.Disable, false) {
+ if r.EnvoyGateway.Provider.Type == egv1a1.ProviderTypeKubernetes &&
+ !ptr.Deref(r.EnvoyGateway.Provider.Kubernetes.LeaderElection.Disable, false) {
go func() {
- select {
- case <-ctx.Done():
- return
- case <-r.Elected:
- initInfra()
- }
+ r.Elected.Wait()
+ initInfra()
}()
return
}
diff --git a/internal/ir/infra.go b/internal/ir/infra.go
index 532c7b079e8..7044b695fda 100644
--- a/internal/ir/infra.go
+++ b/internal/ir/infra.go
@@ -7,6 +7,7 @@ package ir
import (
"cmp"
+ "encoding/json"
"errors"
"fmt"
"reflect"
@@ -29,11 +30,16 @@ type Infra struct {
Proxy *ProxyInfra `json:"proxy" yaml:"proxy"`
}
-func (i Infra) YAMLString() string {
- y, _ := yaml.Marshal(&i)
+func (i *Infra) YAMLString() string {
+ y, _ := yaml.Marshal(i)
return string(y)
}
+func (i *Infra) JSONString() string {
+ j, _ := json.Marshal(i)
+ return string(j)
+}
+
// ProxyInfra defines managed proxy infrastructure.
// +k8s:deepcopy-gen=true
type ProxyInfra struct {
diff --git a/internal/ir/infra_test.go b/internal/ir/infra_test.go
index dcc1e0324d5..92781e06c61 100644
--- a/internal/ir/infra_test.go
+++ b/internal/ir/infra_test.go
@@ -116,7 +116,6 @@ func TestValidateInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := tc.infra.Validate()
if !tc.expect {
@@ -142,7 +141,6 @@ func TestNewInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
actual := NewInfra()
require.Equal(t, tc.expected, actual)
@@ -165,7 +163,6 @@ func TestNewProxyInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
actual := NewProxyInfra()
require.Equal(t, tc.expected, actual)
@@ -205,7 +202,6 @@ func TestObjectName(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
actual := tc.infra.Proxy.ObjectName()
require.Equal(t, tc.expected, actual)
diff --git a/internal/ir/xds.go b/internal/ir/xds.go
index 3d300f1a539..4db7b8445aa 100644
--- a/internal/ir/xds.go
+++ b/internal/ir/xds.go
@@ -7,7 +7,10 @@ package ir
import (
"cmp"
+ "encoding"
+ "encoding/json"
"errors"
+ "fmt"
"net/http"
"net/netip"
"reflect"
@@ -25,6 +28,10 @@ import (
egv1a1validation "github.com/envoyproxy/gateway/api/v1alpha1/validation"
)
+const (
+ EmptyPath = ""
+)
+
var (
ErrListenerNameEmpty = errors.New("field Name must be specified")
ErrListenerAddressInvalid = errors.New("field Address must be a valid IP address")
@@ -41,12 +48,15 @@ var (
ErrDestEndpointUDSPortInvalid = errors.New("field Port must not be specified for Unix Domain Socket address")
ErrDestEndpointUDSHostInvalid = errors.New("field Host must not be specified for Unix Domain Socket address")
ErrStringMatchConditionInvalid = errors.New("only one of the Exact, Prefix, SafeRegex or Distinct fields must be set")
+ ErrStringMatchInvertDistinctInvalid = errors.New("only one of the Invert or Distinct fields can be set")
ErrStringMatchNameIsEmpty = errors.New("field Name must be specified")
ErrDirectResponseStatusInvalid = errors.New("only HTTP status codes 100 - 599 are supported for DirectResponse")
ErrRedirectUnsupportedStatus = errors.New("only HTTP status codes 301 and 302 are supported for redirect filters")
ErrRedirectUnsupportedScheme = errors.New("only http and https are supported for the scheme in redirect filters")
- ErrHTTPPathModifierDoubleReplace = errors.New("redirect filter cannot have a path modifier that supplies both fullPathReplace and prefixMatchReplace")
- ErrHTTPPathModifierNoReplace = errors.New("redirect filter cannot have a path modifier that does not supply either fullPathReplace or prefixMatchReplace")
+ ErrHTTPPathModifierDoubleReplace = errors.New("redirect filter cannot have a path modifier that supplies more than one of fullPathReplace, prefixMatchReplace and regexMatchReplace")
+ ErrHTTPPathModifierNoReplace = errors.New("redirect filter cannot have a path modifier that does not supply either fullPathReplace, prefixMatchReplace or regexMatchReplace")
+ ErrHTTPPathRegexModifierNoSetting = errors.New("redirect filter cannot have a path modifier that does not supply either fullPathReplace, prefixMatchReplace or regexMatchReplace")
+ ErrHTTPHostModifierDoubleReplace = errors.New("redirect filter cannot have a host modifier that supplies more than one of Hostname, Header and Backend")
ErrAddHeaderEmptyName = errors.New("header modifier filter cannot configure a header without a name to be added")
ErrAddHeaderDuplicate = errors.New("header modifier filter attempts to add the same header more than once (case insensitive)")
ErrRemoveHeaderDuplicate = errors.New("header modifier filter attempts to remove the same header more than once (case insensitive)")
@@ -68,6 +78,51 @@ var (
redacted = []byte("[redacted]")
)
+// PrivateBytes implements a custom []byte type so that we can override the
+// various string-ish printing functions to redact the contents.
+type PrivateBytes []byte
+
+var (
+ _ fmt.Stringer = PrivateBytes{}
+ _ encoding.TextMarshaler = PrivateBytes{}
+)
+
+// MarshalText redacts the contents of the PrivateBytes type.
+// Note that MarshalJSON will call MarshalText if it exists, so we don't
+// need to implement MarshalJSON.
+func (p PrivateBytes) MarshalText() ([]byte, error) {
+ if len(p) == 0 {
+ return nil, nil
+ }
+ return redacted, nil
+}
+
+// String redacts the contents of the PrivateBytes type.
+func (p PrivateBytes) String() string {
+ if len(p) == 0 {
+ return ""
+ }
+ return string(redacted)
+}
+
+func (p *PrivateBytes) UnmarshalJSON(data []byte) error {
+ if len(data) == 0 {
+ *p = nil
+ return nil
+ }
+ if string(data) == `"`+string(redacted)+`"` {
+ *p = redacted
+ return nil
+ }
+ var b []byte
+ err := json.Unmarshal(data, &b)
+ if err != nil {
+ return fmt.Errorf("UnmarshalJSON failed: %w, %q", err, string(data))
+ }
+ *p = b
+ return err
+}
+
// Xds holds the intermediate representation of a Gateway and is
// used by the xDS Translator to convert it into xDS resources.
// +k8s:deepcopy-gen=true
@@ -119,7 +174,7 @@ func (x *Xds) sort() {
}
// Validate the fields within the Xds structure.
-func (x Xds) Validate() error {
+func (x *Xds) Validate() error {
var errs error
for _, http := range x.HTTP {
if err := http.Validate(); err != nil {
@@ -139,7 +194,7 @@ func (x Xds) Validate() error {
return errs
}
-func (x Xds) GetHTTPListener(name string) *HTTPListener {
+func (x *Xds) GetHTTPListener(name string) *HTTPListener {
for _, listener := range x.HTTP {
if listener.Name == name {
return listener
@@ -148,7 +203,7 @@ func (x Xds) GetHTTPListener(name string) *HTTPListener {
return nil
}
-func (x Xds) GetTCPListener(name string) *TCPListener {
+func (x *Xds) GetTCPListener(name string) *TCPListener {
for _, listener := range x.TCP {
if listener.Name == name {
return listener
@@ -157,7 +212,7 @@ func (x Xds) GetTCPListener(name string) *TCPListener {
return nil
}
-func (x Xds) GetUDPListener(name string) *UDPListener {
+func (x *Xds) GetUDPListener(name string) *UDPListener {
for _, listener := range x.UDP {
if listener.Name == name {
return listener
@@ -166,30 +221,14 @@ func (x Xds) GetUDPListener(name string) *UDPListener {
return nil
}
-func (x Xds) YAMLString() string {
- y, _ := yaml.Marshal(x.Printable())
+func (x *Xds) YAMLString() string {
+ y, _ := yaml.Marshal(x)
return string(y)
}
-// Printable returns a deep copy of the resource that can be safely logged.
-func (x Xds) Printable() *Xds {
- out := x.DeepCopy()
- for _, listener := range out.HTTP {
- // Omit field
- if listener.TLS != nil {
- for i := range listener.TLS.Certificates {
- listener.TLS.Certificates[i].PrivateKey = redacted
- }
- }
-
- for _, route := range listener.Routes {
- // Omit field
- if route.Security != nil {
- route.Security = route.Security.Printable()
- }
- }
- }
- return out
+func (x *Xds) JSONString() string {
+ j, _ := json.Marshal(x)
+ return string(j)
}
type Listener interface {
@@ -211,8 +250,13 @@ type CoreListenerDetails struct {
ExtensionRefs []*UnstructuredRef `json:"extensionRefs,omitempty" yaml:"extensionRefs,omitempty"`
// Metadata is used to enrich envoy resource metadata with user and provider-specific information
Metadata *ResourceMetadata `json:"metadata,omitempty" yaml:"metadata,omitempty"`
+ // IPFamily specifies the IP address family used by the Gateway for its listening ports.
+ IPFamily *IPFamily `json:"ipFamily,omitempty" yaml:"ipFamily,omitempty"`
}
+// IPFamily specifies the IP address family used by the Gateway for its listening ports.
+type IPFamily = egv1a1.IPFamily
+
func (l CoreListenerDetails) GetName() string {
return l.Name
}
@@ -337,7 +381,11 @@ type TLSConfig struct {
// SignatureAlgorithms supported by this listener
SignatureAlgorithms []string `json:"signatureAlgorithms,omitempty" yaml:"signatureAlgorithms,omitempty"`
// ALPNProtocols exposed by this listener
- ALPNProtocols []string `json:"alpnProtocols,omitempty" yaml:"alpnProtocols,omitempty"`
+ ALPNProtocols []string `json:"alpnProtocols" yaml:"alpnProtocols"`
+ // StatelessSessionResumption determines if stateless (session-ticket based) session resumption is enabled
+ StatelessSessionResumption bool `json:"statelessSessionResumption,omitempty" yaml:"statelessSessionResumption,omitempty"`
+ // StatefulSessionResumption determines if stateful (session-id based) session resumption is enabled
+ StatefulSessionResumption bool `json:"statefulSessionResumption,omitempty" yaml:"statefulSessionResumption,omitempty"`
}
// TLSCertificate holds a single certificate's details
@@ -348,7 +396,7 @@ type TLSCertificate struct {
// Certificate can be either a client or server certificate.
Certificate []byte `json:"serverCertificate,omitempty" yaml:"serverCertificate,omitempty"`
// PrivateKey for the server.
- PrivateKey []byte `json:"privateKey,omitempty" yaml:"privateKey,omitempty"`
+ PrivateKey PrivateBytes `json:"privateKey,omitempty" yaml:"privateKey,omitempty"`
}
// TLSCACertificate holds CA Certificate to validate clients
@@ -456,6 +504,78 @@ type HTTP2Settings struct {
InitialConnectionWindowSize *uint32 `json:"initialStreamWindowSize,omitempty" yaml:"initialStreamWindowSize,omitempty"`
// MaxConcurrentStreams is the maximum number of concurrent streams that can be opened on a connection.
MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty" yaml:"maxConcurrentStreams,omitempty"`
+ // ResetStreamOnError determines if a stream or connection is reset on messaging error.
+ ResetStreamOnError *bool `json:"resetStreamOnError,omitempty" yaml:"resetStreamOnError,omitempty"`
+}
+
+// ResponseOverride defines the configuration to override specific responses with a custom one.
+// +k8s:deepcopy-gen=true
+type ResponseOverride struct {
+ // Name is a unique name for a ResponseOverride configuration.
+ // The xds translator only generates one CustomResponse filter for each unique name.
+ Name string `json:"name" yaml:"name"`
+
+ // Rules contains the list of rules to override responses.
+ Rules []ResponseOverrideRule `json:"rules,omitempty"`
+}
+
+// ResponseOverrideRule defines the configuration for overriding a response.
+// +k8s:deepcopy-gen=true
+type ResponseOverrideRule struct {
+ // Name is a generated name for the rule.
+ Name string `json:"name"`
+ // Match configuration.
+ Match CustomResponseMatch `json:"match"`
+ // Response configuration.
+ Response CustomResponse `json:"response"`
+}
+
+// CustomResponseMatch defines the configuration for matching a user response to return a custom one.
+// +k8s:deepcopy-gen=true
+type CustomResponseMatch struct {
+ // Status code to match on. The match evaluates to true if any of the matches are successful.
+ StatusCodes []StatusCodeMatch `json:"statusCodes"`
+}
+
+// StatusCodeMatch defines the configuration for matching a status code.
+// +k8s:deepcopy-gen=true
+type StatusCodeMatch struct {
+ // Value contains the value of the status code.
+ Value *int `json:"value,omitempty"`
+
+ // Range contains a range of status codes.
+ Range *StatusCodeRange `json:"range,omitempty"`
+}
+
+// StatusCodeRange defines the configuration for define a range of status codes.
+type StatusCodeRange struct {
+ // Start of the range, including the start value.
+ Start int `json:"start"`
+ // End of the range, including the end value.
+ End int `json:"end"`
+}
+
+// CustomResponse defines the configuration for returning a custom response.
+// +k8s:deepcopy-gen=true
+type CustomResponse struct {
+ // Content Type of the response. This will be set in the Content-Type header.
+ ContentType *string `json:"contentType,omitempty"`
+
+ // Body of the Custom Response
+ Body *string `json:"body,omitempty"`
+
+ // StatusCode will be used for the response's status code.
+ StatusCode *uint32 `json:"statusCode,omitempty"`
+}
+
+// Validate the fields within the CustomResponse structure
+func (r *CustomResponse) Validate() error {
+ var errs error
+ if status := r.StatusCode; status != nil && (*status > 599 || *status < 100) {
+ errs = errors.Join(errs, ErrDirectResponseStatusInvalid)
+ }
+
+ return errs
}
// HealthCheckSettings provides HealthCheck configuration on the HTTP/HTTPS listener.
@@ -488,6 +608,12 @@ type HeaderSettings struct {
// (Edge request is the request from external clients to front Envoy) and not reset it, which is the current Envoy behaviour.
// It defaults to false.
PreserveXRequestID bool `json:"preserveXRequestID,omitempty" yaml:"preserveXRequestID,omitempty"`
+
+ // EarlyAddRequestHeaders defines headers that would be added before envoy request processing.
+ EarlyAddRequestHeaders []AddHeader `json:"earlyAddRequestHeaders,omitempty" yaml:"earlyAddRequestHeaders,omitempty"`
+
+ // EarlyRemoveRequestHeaders defines headers that would be removed before envoy request processing.
+ EarlyRemoveRequestHeaders []string `json:"earlyRemoveRequestHeaders,omitempty" yaml:"earlyRemoveRequestHeaders,omitempty"`
}
// ClientTimeout sets the timeout configuration for downstream connections
@@ -542,7 +668,7 @@ type HTTPRoute struct {
// RemoveResponseHeaders defines a list of headers to be removed from response.
RemoveResponseHeaders []string `json:"removeResponseHeaders,omitempty" yaml:"removeResponseHeaders,omitempty"`
// Direct responses to be returned for this route. Takes precedence over Destinations and Redirect.
- DirectResponse *DirectResponse `json:"directResponse,omitempty" yaml:"directResponse,omitempty"`
+ DirectResponse *CustomResponse `json:"directResponse,omitempty" yaml:"directResponse,omitempty"`
// Redirections to be returned for this route. Takes precedence over Destinations.
Redirect *Redirect `json:"redirect,omitempty" yaml:"redirect,omitempty"`
// Destination that requests to this HTTPRoute will be mirrored to
@@ -563,6 +689,46 @@ type HTTPRoute struct {
UseClientProtocol *bool `json:"useClientProtocol,omitempty" yaml:"useClientProtocol,omitempty"`
// Metadata is used to enrich envoy route metadata with user and provider-specific information
Metadata *ResourceMetadata `json:"metadata,omitempty" yaml:"metadata,omitempty"`
+ // SessionPersistence holds the configuration for session persistence.
+ SessionPersistence *SessionPersistence `json:"sessionPersistence,omitempty" yaml:"sessionPersistence,omitempty"`
+ // Timeout is the time until which entire response is received from the upstream.
+ Timeout *metav1.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"`
+}
+
+// DNS contains configuration options for DNS resolution.
+// +k8s:deepcopy-gen=true
+type DNS struct {
+ // DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ DNSRefreshRate *metav1.Duration `json:"dnsRefreshRate,omitempty"`
+ // RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ RespectDNSTTL *bool `json:"respectDnsTtl,omitempty"`
+}
+
+// SessionPersistence defines the desired state of SessionPersistence.
+// +k8s:deepcopy-gen=true
+type SessionPersistence struct {
+ // Cookie defines the configuration for cookie-based session persistence.
+ // Either Cookie or Header must be non-empty.
+ Cookie *CookieBasedSessionPersistence `json:"cookie,omitempty" yaml:"cookie,omitempty"`
+ // Header defines the configuration for header-based session persistence.
+ // Either Cookie or Header must be non-empty.
+ Header *HeaderBasedSessionPersistence `json:"header,omitempty" yaml:"header,omitempty"`
+}
+
+// CookieBasedSessionPersistence defines the configuration for cookie-based session persistence.
+// +k8s:deepcopy-gen=true
+type CookieBasedSessionPersistence struct {
+ // Name defines the name of the persistent session token.
+ Name string `json:"name"`
+
+ TTL *metav1.Duration `json:"ttl,omitempty" yaml:"ttl,omitempty"`
+}
+
+// HeaderBasedSessionPersistence defines the configuration for header-based session persistence.
+// +k8s:deepcopy-gen=true
+type HeaderBasedSessionPersistence struct {
+ // Name defines the name of the persistent session token.
+ Name string `json:"name"`
}
// TrafficFeatures holds the information associated with the Backend Traffic Policy.
@@ -589,6 +755,13 @@ type TrafficFeatures struct {
Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"`
// settings of upstream connection
BackendConnection *BackendConnection `json:"backendConnection,omitempty" yaml:"backendConnection,omitempty"`
+ // HTTP2 provides HTTP/2 configuration for clusters
+ // +optional
+ HTTP2 *HTTP2Settings `json:"http2,omitempty" yaml:"http2,omitempty"`
+ // DNS is used to configure how DNS resolution is handled by the Envoy Proxy cluster
+ DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"`
+ // ResponseOverride defines the schema for overriding the response.
+ ResponseOverride *ResponseOverride `json:"responseOverride,omitempty" yaml:"responseOverride,omitempty"`
}
func (b *TrafficFeatures) Validate() error {
@@ -625,18 +798,6 @@ type SecurityFeatures struct {
Authorization *Authorization `json:"authorization,omitempty" yaml:"authorization,omitempty"`
}
-func (s *SecurityFeatures) Printable() *SecurityFeatures {
- out := s.DeepCopy()
- if out.OIDC != nil {
- out.OIDC.ClientSecret = redacted
- out.OIDC.HMACSecret = redacted
- }
- if out.BasicAuth != nil {
- out.BasicAuth.Users = redacted
- }
- return out
-}
-
func (s *SecurityFeatures) Validate() error {
var errs error
@@ -667,6 +828,18 @@ type UnstructuredRef struct {
Object *unstructured.Unstructured `json:"object,omitempty" yaml:"object,omitempty"`
}
+// RegexMatchReplace defines the schema for modifying HTTP request path using regex.
+//
+// +k8s:deepcopy-gen=true
+type RegexMatchReplace struct {
+ // Pattern matches a regular expression against the value of the HTTP Path.The regex string must
+ // adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax.
+ Pattern string `json:"pattern" yaml:"pattern"`
+ // Substitution is an expression that replaces the matched portion.The expression may include numbered
+ // capture groups that adhere to syntax documented in https://github.com/google/re2/wiki/Syntax.
+ Substitution string `json:"substitution" yaml:"substitution"`
+}
+
// CORS holds the Cross-Origin Resource Sharing (CORS) policy for the route.
//
// +k8s:deepcopy-gen=true
@@ -718,10 +891,10 @@ type OIDC struct {
// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
//
// This is an Opaque secret. The client secret should be stored in the key "client-secret".
- ClientSecret []byte `json:"clientSecret,omitempty" yaml:"clientSecret,omitempty"`
+ ClientSecret PrivateBytes `json:"clientSecret,omitempty" yaml:"clientSecret,omitempty"`
// HMACSecret is the secret used to sign the HMAC of the OAuth2 filter cookies.
- HMACSecret []byte `json:"hmacSecret,omitempty" yaml:"hmacSecret,omitempty"`
+ HMACSecret PrivateBytes `json:"hmacSecret,omitempty" yaml:"hmacSecret,omitempty"`
// The OIDC scopes to be used in the
// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
@@ -763,9 +936,21 @@ type OIDC struct {
// CookieNameOverrides can optionally override the generated name of the cookies set by the oauth filter.
CookieNameOverrides *egv1a1.OIDCCookieNames `json:"cookieNameOverrides,omitempty"`
+
+ // CookieDomain sets the domain of the cookies set by the oauth filter.
+ CookieDomain *string `json:"cookieDomain,omitempty"`
}
+// OIDCProvider defines the schema for the OIDC Provider.
+//
+// +k8s:deepcopy-gen=true
type OIDCProvider struct {
+ // Destination defines the destination for the OIDC Provider.
+ Destination *RouteDestination `json:"destination,omitempty"`
+
+ // Traffic contains configuration for traffic features for the OIDC Provider
+ Traffic *TrafficFeatures `json:"traffic,omitempty"`
+
// The OIDC Provider's [authorization endpoint](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint).
AuthorizationEndpoint string `json:"authorizationEndpoint,omitempty"`
@@ -782,7 +967,7 @@ type BasicAuth struct {
Name string `json:"name" yaml:"name"`
// The username-password pairs in htpasswd format.
- Users []byte `json:"users,omitempty" yaml:"users,omitempty"`
+ Users PrivateBytes `json:"users,omitempty" yaml:"users,omitempty"`
}
// ExtAuth defines the schema for the external authorization.
@@ -801,6 +986,9 @@ type ExtAuth struct {
// Only one of GRPCService or HTTPService may be specified.
HTTP *HTTPExtAuthService `json:"http,omitempty"`
+ // Traffic contains configuration for traffic features for the ExtAuth service
+ Traffic *TrafficFeatures `json:"traffic,omitempty"`
+
// HeadersToExtAuth defines the client request headers that will be included
// in the request to the external authorization service.
// Note: If not specified, the default behavior for gRPC and HTTP external
@@ -814,6 +1002,10 @@ type ExtAuth struct {
// +optional
HeadersToExtAuth []string `json:"headersToExtAuth,omitempty"`
+ // BodyToExtAuth defines the Body to Ext Auth configuration.
+ // +optional
+ BodyToExtAuth *BodyToExtAuth `json:"bodyToExtAuth,omitempty"`
+
// FailOpen is a switch used to control the behavior when a response from the External Authorization service cannot be obtained.
// If FailOpen is set to true, the system allows the traffic to pass through.
// Otherwise, if it is set to false or not set (defaulting to false),
@@ -821,6 +1013,23 @@ type ExtAuth struct {
// This setting determines whether to prioritize accessibility over strict security in case of authorization service failure.
// +optional
FailOpen *bool `json:"failOpen,omitempty"`
+
+ // RecomputeRoute clears the route cache and recalculates the routing decision.
+ // This field must be enabled if the headers generated from the claim are used for
+ // route matching decisions. If the recomputation selects a new route, features targeting
+ // the new matched route will be applied.
+ // +optional
+ RecomputeRoute *bool `json:"recomputeRoute,omitempty"`
+}
+
+// BodyToExtAuth defines the Body to Ext Auth configuration
+// +k8s:deepcopy-gen=true
+type BodyToExtAuth struct {
+ // MaxRequestBytes is the maximum size of a message body that the filter will hold in memory.
+ // Envoy will return HTTP 413 and will not initiate the authorization process when buffer
+ // reaches the number set in this field.
+ // Note that this setting will have precedence over failOpen mode.
+ MaxRequestBytes uint32 `json:"maxRequestBytes"`
}
// HTTPExtAuthService defines the HTTP External Authorization service
@@ -890,6 +1099,8 @@ type AuthorizationRule struct {
type Principal struct {
// ClientCIDRs defines the client CIDRs to be matched.
ClientCIDRs []*CIDRMatch `json:"clientCIDRs,omitempty"`
+ // JWT defines the JWT principal to be matched.
+ JWT *egv1a1.JWTPrincipal `json:"jwt,omitempty"`
}
// FaultInjection defines the schema for injecting faults into requests.
@@ -1097,14 +1308,20 @@ type DestinationSetting struct {
// invalid endpoints are represents with a
// non-zero weight with an empty endpoints list
Weight *uint32 `json:"weight,omitempty" yaml:"weight,omitempty"`
+ // Priority default to priority 0, the highest level.
+ // If multiple destinations share the same priority, they will all be utilized.
+ // Lower priority endpoints will be used only if higher priority levels are unavailable.
+ Priority *uint32 `json:"priority,omitempty"`
// Protocol associated with this destination/port.
Protocol AppProtocol `json:"protocol,omitempty" yaml:"protocol,omitempty"`
Endpoints []*DestinationEndpoint `json:"endpoints,omitempty" yaml:"endpoints,omitempty"`
// AddressTypeState specifies the state of DestinationEndpoint address type.
AddressType *DestinationAddressType `json:"addressType,omitempty" yaml:"addressType,omitempty"`
-
- TLS *TLSUpstreamConfig `json:"tls,omitempty" yaml:"tls,omitempty"`
- Filters *DestinationFilters `json:"filters,omitempty" yaml:"filters,omitempty"`
+ // IPFamily specifies the IP family (IPv4 or IPv6) to use for this destination's endpoints.
+ // This is derived from the backend service and endpoint slice information.
+ IPFamily *IPFamily `json:"ipFamily,omitempty" yaml:"ipFamily,omitempty"`
+ TLS *TLSUpstreamConfig `json:"tls,omitempty" yaml:"tls,omitempty"`
+ Filters *DestinationFilters `json:"filters,omitempty" yaml:"filters,omitempty"`
}
// Validate the fields within the RouteDestination structure
@@ -1178,9 +1395,9 @@ func NewDestEndpoint(host string, port uint32) *DestinationEndpoint {
// AddHeader configures a header to be added to a request or response.
// +k8s:deepcopy-gen=true
type AddHeader struct {
- Name string `json:"name" yaml:"name"`
- Value string `json:"value" yaml:"value"`
- Append bool `json:"append" yaml:"append"`
+ Name string `json:"name" yaml:"name"`
+ Value []string `json:"value" yaml:"value"`
+ Append bool `json:"append" yaml:"append"`
}
// Validate the fields within the AddHeader structure
@@ -1193,30 +1410,13 @@ func (h AddHeader) Validate() error {
return errs
}
-// DirectResponse holds the details for returning a body and status code for a route.
-// +k8s:deepcopy-gen=true
-type DirectResponse struct {
- // StatusCode will be used for the direct response's status code.
- StatusCode uint32 `json:"statusCode" yaml:"statusCode"`
-}
-
-// Validate the fields within the DirectResponse structure
-func (r DirectResponse) Validate() error {
- var errs error
- if status := r.StatusCode; status > 599 || status < 100 {
- errs = errors.Join(errs, ErrDirectResponseStatusInvalid)
- }
-
- return errs
-}
-
// URLRewrite holds the details for how to rewrite a request
// +k8s:deepcopy-gen=true
type URLRewrite struct {
// Path contains config for rewriting the path of the request.
- Path *HTTPPathModifier `json:"path,omitempty" yaml:"path,omitempty"`
- // Hostname configures the replacement of the request's hostname.
- Hostname *string `json:"hostname,omitempty" yaml:"hostname,omitempty"`
+ Path *ExtendedHTTPPathModifier `json:"path,omitempty" yaml:"path,omitempty"`
+ // Host configures the replacement of the request's host header.
+ Host *HTTPHostModifier `json:"host,omitempty" yaml:"host,omitempty"`
}
// Validate the fields within the URLRewrite structure
@@ -1229,6 +1429,12 @@ func (r URLRewrite) Validate() error {
}
}
+ if r.Host != nil {
+ if err := r.Host.Validate(); err != nil {
+ errs = errors.Join(errs, err)
+ }
+ }
+
return errs
}
@@ -1296,6 +1502,70 @@ func (r HTTPPathModifier) Validate() error {
return errs
}
+// ExtendedHTTPPathModifier holds instructions for how to modify the path of a request on a redirect response
+// with both core gateway-api and extended envoy gateway capabilities
+// +k8s:deepcopy-gen=true
+type ExtendedHTTPPathModifier struct {
+ HTTPPathModifier `json:",inline" yaml:",inline"`
+ // RegexMatchReplace provides a regex to match an a replacement to perform on the path.
+ RegexMatchReplace *RegexMatchReplace `json:"regexMatchReplace,omitempty" yaml:"regexMatchReplace,omitempty"`
+}
+
+// Validate the fields within the HTTPPathModifier structure
+func (r ExtendedHTTPPathModifier) Validate() error {
+ var errs error
+
+ rewrites := []bool{r.RegexMatchReplace != nil, r.PrefixMatchReplace != nil, r.FullReplace != nil}
+ rwc := 0
+ for _, rw := range rewrites {
+ if rw {
+ rwc++
+ }
+ }
+
+ if rwc > 1 {
+ errs = errors.Join(errs, ErrHTTPPathModifierDoubleReplace)
+ }
+
+ if r.FullReplace == nil && r.PrefixMatchReplace == nil && r.RegexMatchReplace == nil {
+ errs = errors.Join(errs, ErrHTTPPathModifierNoReplace)
+ }
+
+ if r.RegexMatchReplace != nil && (r.RegexMatchReplace.Pattern == "" || r.RegexMatchReplace.Substitution == "") {
+ errs = errors.Join(errs, ErrHTTPPathModifierNoReplace)
+ }
+
+ return errs
+}
+
+// HTTPHostModifier holds instructions for how to modify the host of a request
+// with both core gateway-api and extended envoy gateway capabilities
+// +k8s:deepcopy-gen=true
+type HTTPHostModifier struct {
+ Name *string `json:"name,omitempty" yaml:"name,omitempty"`
+ Header *string `json:"header,omitempty" yaml:"header,omitempty"`
+ Backend *bool `json:"backend,omitempty" yaml:"backend,omitempty"`
+}
+
+// Validate the fields within the HTTPPathModifier structure
+func (r HTTPHostModifier) Validate() error {
+ var errs error
+
+ rewrites := []bool{r.Name != nil, r.Header != nil, r.Backend != nil}
+ rwc := 0
+ for _, rw := range rewrites {
+ if rw {
+ rwc++
+ }
+ }
+
+ if rwc > 1 {
+ errs = errors.Join(errs, ErrHTTPHostModifierDoubleReplace)
+ }
+
+ return errs
+}
+
// StringMatch holds the various match conditions.
// Only one of Exact, Prefix, SafeRegex or Distinct can be set.
// +k8s:deepcopy-gen=true
@@ -1313,6 +1583,8 @@ type StringMatch struct {
// Distinct match condition.
// Used to match any and all possible unique values encountered within the Name field.
Distinct bool `json:"distinct" yaml:"distinct"`
+ // Invert inverts the final match decision
+ Invert *bool `json:"invert,omitempty" yaml:"invert,omitempty"`
}
// Validate the fields within the StringMatch structure
@@ -1335,6 +1607,9 @@ func (s StringMatch) Validate() error {
if s.Name == "" {
errs = errors.Join(errs, ErrStringMatchNameIsEmpty)
}
+ if s.Invert != nil && *s.Invert {
+ errs = errors.Join(errs, ErrStringMatchInvertDistinctInvalid)
+ }
matchCount++
}
@@ -1386,6 +1661,8 @@ type TCPRoute struct {
ProxyProtocol *ProxyProtocol `json:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty"`
// settings of upstream connection
BackendConnection *BackendConnection `json:"backendConnection,omitempty" yaml:"backendConnection,omitempty"`
+ // DNS is used to configure how DNS resolution is handled for the route
+ DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"`
}
// TLS holds information for configuring TLS on a listener
@@ -1420,6 +1697,7 @@ func (t TCPListener) Validate() error {
func (t TCPRoute) Validate() error {
var errs error
+
if t.Name == "" {
errs = errors.Join(errs, ErrRouteNameEmpty)
}
@@ -1492,10 +1770,8 @@ type UDPRoute struct {
Destination *RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"`
// load balancer policy to use when routing to the backend endpoints.
LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty"`
- // Request and connection timeout settings
- Timeout *Timeout `json:"timeout,omitempty" yaml:"timeout,omitempty"`
- // settings of upstream connection
- BackendConnection *BackendConnection `json:"backendConnection,omitempty" yaml:"backendConnection,omitempty"`
+ // DNS is used to configure how DNS resolution is handled by the Envoy Proxy cluster
+ DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"`
}
// Validate the fields within the UDPListener structure
@@ -1603,6 +1879,13 @@ type RateLimitValue struct {
Unit RateLimitUnit `json:"unit" yaml:"unit"`
}
+type ProxyAccessLogType egv1a1.ProxyAccessLogType
+
+const (
+ ProxyAccessLogTypeRoute = ProxyAccessLogType(egv1a1.ProxyAccessLogTypeRoute)
+ ProxyAccessLogTypeListener = ProxyAccessLogType(egv1a1.ProxyAccessLogTypeListener)
+)
+
// AccessLog holds the access logging configuration.
// +k8s:deepcopy-gen=true
type AccessLog struct {
@@ -1615,17 +1898,19 @@ type AccessLog struct {
// TextAccessLog holds the configuration for text access logging.
// +k8s:deepcopy-gen=true
type TextAccessLog struct {
- CELMatches []string `json:"celMatches,omitempty" yaml:"celMatches,omitempty"`
- Format *string `json:"format,omitempty" yaml:"format,omitempty"`
- Path string `json:"path" yaml:"path"`
+ CELMatches []string `json:"celMatches,omitempty" yaml:"celMatches,omitempty"`
+ Format *string `json:"format,omitempty" yaml:"format,omitempty"`
+ Path string `json:"path" yaml:"path"`
+ LogType *ProxyAccessLogType `json:"logType,omitempty" yaml:"logType,omitempty"`
}
// JSONAccessLog holds the configuration for JSON access logging.
// +k8s:deepcopy-gen=true
type JSONAccessLog struct {
- CELMatches []string `json:"celMatches,omitempty" yaml:"celMatches,omitempty"`
- JSON map[string]string `json:"json,omitempty" yaml:"json,omitempty"`
- Path string `json:"path" yaml:"path"`
+ CELMatches []string `json:"celMatches,omitempty" yaml:"celMatches,omitempty"`
+ JSON map[string]string `json:"json,omitempty" yaml:"json,omitempty"`
+ Path string `json:"path" yaml:"path"`
+ LogType *ProxyAccessLogType `json:"logType,omitempty" yaml:"logType,omitempty"`
}
// ALSAccessLog holds the configuration for gRPC ALS access logging.
@@ -1634,10 +1919,12 @@ type ALSAccessLog struct {
CELMatches []string `json:"celMatches,omitempty" yaml:"celMatches,omitempty"`
LogName string `json:"name" yaml:"name"`
Destination RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"`
+ Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"`
Type egv1a1.ALSEnvoyProxyAccessLogType `json:"type" yaml:"type"`
Text *string `json:"text,omitempty" yaml:"text,omitempty"`
Attributes map[string]string `json:"attributes,omitempty" yaml:"attributes,omitempty"`
HTTP *ALSAccessLogHTTP `json:"http,omitempty" yaml:"http,omitempty"`
+ LogType *ProxyAccessLogType `json:"logType,omitempty" yaml:"logType,omitempty"`
}
// ALSAccessLogHTTP holds the configuration for HTTP ALS access logging.
@@ -1651,12 +1938,14 @@ type ALSAccessLogHTTP struct {
// OpenTelemetryAccessLog holds the configuration for OpenTelemetry access logging.
// +k8s:deepcopy-gen=true
type OpenTelemetryAccessLog struct {
- CELMatches []string `json:"celMatches,omitempty" yaml:"celMatches,omitempty"`
- Authority string `json:"authority,omitempty" yaml:"authority,omitempty"`
- Text *string `json:"text,omitempty" yaml:"text,omitempty"`
- Attributes map[string]string `json:"attributes,omitempty" yaml:"attributes,omitempty"`
- Resources map[string]string `json:"resources,omitempty" yaml:"resources,omitempty"`
- Destination RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"`
+ CELMatches []string `json:"celMatches,omitempty" yaml:"celMatches,omitempty"`
+ Authority string `json:"authority,omitempty" yaml:"authority,omitempty"`
+ Text *string `json:"text,omitempty" yaml:"text,omitempty"`
+ Attributes map[string]string `json:"attributes,omitempty" yaml:"attributes,omitempty"`
+ Resources map[string]string `json:"resources,omitempty" yaml:"resources,omitempty"`
+ Destination RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"`
+ Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"`
+ LogType *ProxyAccessLogType `json:"logType,omitempty" yaml:"logType,omitempty"`
}
// EnvoyPatchPolicy defines the intermediate representation of the EnvoyPatchPolicy resource.
@@ -1689,15 +1978,50 @@ type JSONPatchConfig struct {
Operation JSONPatchOperation `json:"operation" yaml:"operation"`
}
+type JSONPatchOp string
+
+const (
+ JSONPatchOpAdd JSONPatchOp = "add"
+ JSONPatchOpRemove JSONPatchOp = "remove"
+ JSONPatchOpReplace JSONPatchOp = "replace"
+ JSONPatchOpCopy JSONPatchOp = "copy"
+ JSONPatchOpMove JSONPatchOp = "move"
+ JSONPatchOpTest JSONPatchOp = "test"
+)
+
+func TranslateJSONPatchOp(op egv1a1.JSONPatchOperationType) JSONPatchOp {
+ switch op {
+ case "add":
+ return JSONPatchOpAdd
+ case "remove":
+ return JSONPatchOpRemove
+ case "replace":
+ return JSONPatchOpReplace
+ case "move":
+ return JSONPatchOpMove
+ case "copy":
+ return JSONPatchOpCopy
+ case "test":
+ return JSONPatchOpTest
+ default:
+ return ""
+ }
+}
+
// JSONPatchOperation defines the JSON Patch Operation as defined in
// https://datatracker.ietf.org/doc/html/rfc6902
// +k8s:deepcopy-gen=true
type JSONPatchOperation struct {
// Op is the type of operation to perform
- Op string `json:"op" yaml:"op"`
+ Op JSONPatchOp `json:"op" yaml:"op"`
// Path is the location of the target document/field where the operation will be performed
// Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
- Path string `json:"path" yaml:"path"`
+ // +optional
+ Path *string `json:"path,omitempty" yaml:"path,omitempty"`
+ // JSONPath specifies the locations of the target document/field where the operation will be performed
+ // Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details.
+ // +optional
+ JSONPath *string `json:"jsonPath,omitempty" yaml:"jsonPath,omitempty"`
// From is the source location of the value to be copied or moved. Only valid
// for move or copy operations
// Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
@@ -1707,6 +2031,45 @@ type JSONPatchOperation struct {
Value *apiextensionsv1.JSON `json:"value,omitempty" yaml:"value,omitempty"`
}
+func (o *JSONPatchOperation) IsPathNilOrEmpty() bool {
+ return o.Path == nil || *o.Path == EmptyPath
+}
+
+func (o *JSONPatchOperation) IsJSONPathNilOrEmpty() bool {
+ return o.JSONPath == nil || *o.JSONPath == EmptyPath
+}
+
+// Validate ensures that the appropriate fields are set for each operation type according to RFC 6902:
+// https://www.rfc-editor.org/rfc/rfc6902.html
+func (o *JSONPatchOperation) Validate() error {
+ if o.Path == nil && o.JSONPath == nil {
+ return fmt.Errorf("a patch operation must specify a path or jsonPath")
+ }
+ switch o.Op {
+ case JSONPatchOpAdd, JSONPatchOpReplace, JSONPatchOpTest:
+ if o.Value == nil {
+ return fmt.Errorf("the %s operation requires a value", o.Op)
+ }
+ if o.From != nil {
+ return fmt.Errorf("the %s operation doesn't support a from attribute", o.Op)
+ }
+ case JSONPatchOpRemove:
+ if o.From != nil || o.Value != nil {
+ return fmt.Errorf("value and from can't be specified with the remove operation")
+ }
+ case JSONPatchOpMove, JSONPatchOpCopy:
+ if o.From == nil {
+ return fmt.Errorf("the %s operation requires a valid from attribute", o.Op)
+ }
+ if o.Value != nil {
+ return fmt.Errorf("the %s operation doesn't support a value attribute", o.Op)
+ }
+ default:
+ return fmt.Errorf("unsupported JSONPatch operation")
+ }
+ return nil
+}
+
// Tracing defines the configuration for tracing a Envoy xDS Resource
// +k8s:deepcopy-gen=true
type Tracing struct {
@@ -1715,14 +2078,16 @@ type Tracing struct {
SamplingRate float64 `json:"samplingRate,omitempty"`
CustomTags map[string]egv1a1.CustomTag `json:"customTags,omitempty"`
Destination RouteDestination `json:"destination,omitempty"`
+ Traffic *TrafficFeatures `json:"traffic,omitempty"`
Provider egv1a1.TracingProvider `json:"provider"`
}
// Metrics defines the configuration for metrics generated by Envoy
// +k8s:deepcopy-gen=true
type Metrics struct {
- EnableVirtualHostStats bool `json:"enableVirtualHostStats" yaml:"enableVirtualHostStats"`
- EnablePerEndpointStats bool `json:"enablePerEndpointStats" yaml:"enablePerEndpointStats"`
+ EnableVirtualHostStats bool `json:"enableVirtualHostStats" yaml:"enableVirtualHostStats"`
+ EnablePerEndpointStats bool `json:"enablePerEndpointStats" yaml:"enablePerEndpointStats"`
+ EnableRequestResponseSizesStats bool `json:"enableRequestResponseSizesStats" yaml:"enableRequestResponseSizesStats"`
}
// TCPKeepalive define the TCP Keepalive configuration.
@@ -1896,6 +2261,8 @@ type ActiveHealthCheck struct {
HTTP *HTTPHealthChecker `json:"http,omitempty" yaml:"http,omitempty"`
// TCP defines the configuration of tcp health checker.
TCP *TCPHealthChecker `json:"tcp,omitempty" yaml:"tcp,omitempty"`
+ // GRPC defines if the GRPC healthcheck service should be used
+ GRPC *GRPCHealthChecker `json:"grpc,omitempty" yaml:"grpc,omitempty"`
}
func (h *HealthCheck) SetHTTPHostIfAbsent(host string) {
@@ -1928,6 +2295,9 @@ func (h *HealthCheck) Validate() error {
if h.Active.TCP != nil {
matchCount++
}
+ if h.Active.GRPC != nil {
+ matchCount++
+ }
if matchCount > 1 {
errs = errors.Join(errs, ErrHealthCheckerInvalid)
}
@@ -2022,6 +2392,15 @@ func (h HTTPStatus) Validate() error {
return nil
}
+// GRPCHealthChecker defines the settings of the gRPC health check.
+// +k8s:deepcopy-gen=true
+type GRPCHealthChecker struct {
+ // Service is the name of a specific service hosted by the server for
+ // which the health check should be requested. If not specified, then the default
+ // is to send a health check request for the entire server.
+ Service *string `json:"service,omitempty" yaml:"service,omitempty"`
+}
+
// TCPHealthChecker defines the settings of tcp health check.
// +k8s:deepcopy-gen=true
type TCPHealthChecker struct {
@@ -2211,6 +2590,9 @@ type ExtProc struct {
// Destination defines the destination for the gRPC External Processing service.
Destination RouteDestination `json:"destination" yaml:"destination"`
+ // Traffic holds the features associated with traffic management
+ Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"`
+
// Authority is the hostname:port of the HTTP External Processing service.
Authority string `json:"authority" yaml:"authority"`
@@ -2232,6 +2614,14 @@ type ExtProc struct {
// ResponseBodyProcessingMode Defines response body processing
ResponseBodyProcessingMode *ExtProcBodyProcessingMode `json:"responseBodyProcessingMode,omitempty" yaml:"responseBodyProcessingMode,omitempty"`
+
+ // RequestAttributes defines which envoy attributes are provided as context to external processor
+ // when processing requests
+ RequestAttributes []string `json:"requestAttributes,omitempty" yaml:"requestAttributes,omitempty"`
+
+ // ResponseAttributes defines which envoy attributes are provided as context to external processor
+ // when processing responses
+ ResponseAttributes []string `json:"responseAttributes,omitempty" yaml:"responseAttributes,omitempty"`
}
// Wasm holds the information associated with the Wasm extensions.
@@ -2264,6 +2654,10 @@ type Wasm struct {
// original URL(either an HTTP URL or an OCI image) and serves it through the
// local HTTP server.
Code *HTTPWasmCode `json:"httpWasmCode,omitempty"`
+
+ // HostKeys is a list of keys for environment variables from the host envoy process
+ // that should be passed into the Wasm VM.
+ HostKeys []string `json:"hostKeys,omitempty"`
}
// HTTPWasmCode holds the information associated with the HTTP Wasm code source.
diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go
index 9492c378344..c73faf7eb44 100644
--- a/internal/ir/xds_test.go
+++ b/internal/ir/xds_test.go
@@ -6,6 +6,7 @@
package ir
import (
+ "encoding/json"
"net/http"
"testing"
"time"
@@ -13,6 +14,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
@@ -253,8 +255,8 @@ var (
PathMatch: &StringMatch{
Exact: ptr.To("filter-error"),
},
- DirectResponse: &DirectResponse{
- StatusCode: uint32(500),
+ DirectResponse: &CustomResponse{
+ StatusCode: ptr.To(uint32(500)),
},
}
@@ -295,8 +297,8 @@ var (
PathMatch: &StringMatch{
Exact: ptr.To("redirect"),
},
- DirectResponse: &DirectResponse{
- StatusCode: uint32(799),
+ DirectResponse: &CustomResponse{
+ StatusCode: ptr.To(uint32(799)),
},
}
@@ -307,9 +309,13 @@ var (
Exact: ptr.To("rewrite"),
},
URLRewrite: &URLRewrite{
- Hostname: ptr.To("rewrite.example.com"),
- Path: &HTTPPathModifier{
- FullReplace: ptr.To("/rewrite"),
+ Host: &HTTPHostModifier{
+ Name: ptr.To("rewrite.example.com"),
+ },
+ Path: &ExtendedHTTPPathModifier{
+ HTTPPathModifier: HTTPPathModifier{
+ FullReplace: ptr.To("/rewrite"),
+ },
},
},
}
@@ -321,10 +327,14 @@ var (
Exact: ptr.To("rewrite"),
},
URLRewrite: &URLRewrite{
- Hostname: ptr.To("rewrite.example.com"),
- Path: &HTTPPathModifier{
- FullReplace: ptr.To("/rewrite"),
- PrefixMatchReplace: ptr.To("/rewrite"),
+ Host: &HTTPHostModifier{
+ Name: ptr.To("rewrite.example.com"),
+ },
+ Path: &ExtendedHTTPPathModifier{
+ HTTPPathModifier: HTTPPathModifier{
+ FullReplace: ptr.To("/rewrite"),
+ PrefixMatchReplace: ptr.To("/rewrite"),
+ },
},
},
}
@@ -338,17 +348,16 @@ var (
AddRequestHeaders: []AddHeader{
{
Name: "example-header",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
{
Name: "example-header-2",
- Value: "example-value-2",
+ Value: []string{"example-value-2"},
Append: false,
},
{
Name: "empty-header",
- Value: "",
Append: false,
},
},
@@ -376,12 +385,12 @@ var (
AddRequestHeaders: []AddHeader{
{
Name: "example-header",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
{
Name: "example-header",
- Value: "example-value-2",
+ Value: []string{"example-value-2"},
Append: false,
},
},
@@ -401,7 +410,7 @@ var (
AddRequestHeaders: []AddHeader{
{
Name: "",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
},
@@ -416,17 +425,16 @@ var (
AddResponseHeaders: []AddHeader{
{
Name: "example-header",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
{
Name: "example-header-2",
- Value: "example-value-2",
+ Value: []string{"example-value-2"},
Append: false,
},
{
Name: "empty-header",
- Value: "",
Append: false,
},
},
@@ -454,12 +462,12 @@ var (
AddResponseHeaders: []AddHeader{
{
Name: "example-header",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
{
Name: "example-header",
- Value: "example-value-2",
+ Value: []string{"example-value-2"},
Append: false,
},
},
@@ -479,7 +487,7 @@ var (
AddResponseHeaders: []AddHeader{
{
Name: "",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
},
@@ -579,7 +587,6 @@ func TestValidateXds(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -634,7 +641,6 @@ func TestValidateHTTPListener(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -686,7 +692,6 @@ func TestValidateTCPListener(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -736,7 +741,6 @@ func TestValidateTLSListenerConfig(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -849,7 +853,6 @@ func TestValidateUDPListener(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -1001,7 +1004,6 @@ func TestValidateHTTPRoute(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -1043,7 +1045,6 @@ func TestValidateTCPRoute(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -1169,7 +1170,6 @@ func TestValidateRouteDestination(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -1187,12 +1187,20 @@ func TestValidateStringMatch(t *testing.T) {
want error
}{
{
- name: "happy",
+ name: "happy exact",
input: StringMatch{
Exact: ptr.To("example"),
},
want: nil,
},
+ {
+ name: "happy distinct",
+ input: StringMatch{
+ Distinct: true,
+ Name: "example",
+ },
+ want: nil,
+ },
{
name: "no fields set",
input: StringMatch{},
@@ -1207,9 +1215,17 @@ func TestValidateStringMatch(t *testing.T) {
},
want: ErrStringMatchConditionInvalid,
},
+ {
+ name: "both invert and distinct fields are set",
+ input: StringMatch{
+ Distinct: true,
+ Name: "example",
+ Invert: ptr.To(true),
+ },
+ want: ErrStringMatchInvertDistinctInvalid,
+ },
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -1316,11 +1332,12 @@ func TestValidateLoadBalancer(t *testing.T) {
}
}
-func TestPrintable(t *testing.T) {
+func TestRedaction(t *testing.T) {
tests := []struct {
- name string
- input Xds
- want *Xds
+ name string
+ input Xds
+ want *Xds
+ wantStr string
}{
{
name: "empty",
@@ -1345,11 +1362,59 @@ func TestPrintable(t *testing.T) {
HTTP: []*HTTPListener{&redactedHappyHTTPSListener},
},
},
+ {
+ name: "explicit string check",
+ input: Xds{
+ HTTP: []*HTTPListener{{
+ TLS: &TLSConfig{
+ Certificates: []TLSCertificate{{
+ Name: "server",
+ Certificate: []byte("---"),
+ PrivateKey: []byte("secret"),
+ }},
+ ClientCertificates: []TLSCertificate{{
+ Name: "client",
+ Certificate: []byte("---"),
+ PrivateKey: []byte("secret"),
+ }},
+ },
+ Routes: []*HTTPRoute{{
+ Security: &SecurityFeatures{
+ OIDC: &OIDC{
+ ClientSecret: []byte("secret"),
+ HMACSecret: []byte("secret"),
+ },
+ BasicAuth: &BasicAuth{
+ Users: []byte("secret"),
+ },
+ },
+ }},
+ }},
+ },
+ wantStr: `{"http":[{"name":"","address":"","port":0,"hostnames":null,` +
+ `"tls":{` +
+ `"certificates":[{"name":"server","serverCertificate":"LS0t","privateKey":"[redacted]"}],` +
+ `"clientCertificates":[{"name":"client","serverCertificate":"LS0t","privateKey":"[redacted]"}],` +
+ `"alpnProtocols":null},` +
+ `"routes":[{` +
+ `"name":"","hostname":"","isHTTP2":false,"security":{` +
+ `"oidc":{"name":"","provider":{},"clientID":"","clientSecret":"[redacted]","hmacSecret":"[redacted]"},` +
+ `"basicAuth":{"name":"","users":"[redacted]"}` +
+ `}}],` +
+ `"isHTTP2":false,"path":{"mergeSlashes":false,"escapedSlashesAction":""}}]}`,
+ },
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
- assert.Equal(t, *test.want, *test.input.Printable())
+ if test.want != nil {
+ if test.wantStr != "" {
+ t.Fatalf("Don't set both want and wantStr")
+ }
+ wantJSON, err := json.Marshal(test.want)
+ require.NoError(t, err)
+ test.wantStr = string(wantJSON)
+ }
+ assert.Equal(t, test.wantStr, test.input.JSONString())
})
}
}
@@ -1630,3 +1695,123 @@ func TestValidateHealthCheck(t *testing.T) {
})
}
}
+
+func TestJSONPatchOperationValidation(t *testing.T) {
+ tests := []struct {
+ name string
+ input JSONPatchOperation
+ want *string
+ }{
+ {
+ name: "no path or jsonpath",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("remove")),
+ },
+ want: ptr.To("a patch operation must specify a path or jsonPath"),
+ },
+ {
+ name: "replace with from",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("replace")),
+ JSONPath: ptr.To("$.some.json[@?name=='lala'].key"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte{},
+ },
+ From: ptr.To("/some/from"),
+ },
+ want: ptr.To("the replace operation doesn't support a from attribute"),
+ },
+ {
+ name: "add with no value",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("add")),
+ JSONPath: ptr.To("$.some.json[@?name=='lala'].key"),
+ },
+ want: ptr.To("the add operation requires a value"),
+ },
+ {
+ name: "remove with from",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("remove")),
+ JSONPath: ptr.To("$.some.json[@?name=='lala'].key"),
+ From: ptr.To("/some/from"),
+ },
+ want: ptr.To("value and from can't be specified with the remove operation"),
+ },
+ {
+ name: "remove with value",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("remove")),
+ JSONPath: ptr.To("$.some.json[@?name=='lala'].key"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte{},
+ },
+ },
+ want: ptr.To("value and from can't be specified with the remove operation"),
+ },
+ {
+ name: "move without from",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("move")),
+ JSONPath: ptr.To("$.some.json[@?name=='lala'].key"),
+ },
+ want: ptr.To("the move operation requires a valid from attribute"),
+ },
+ {
+ name: "copy with value",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("copy")),
+ JSONPath: ptr.To("$.some.json[@?name=='lala'].key"),
+ From: ptr.To("/some/from"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte{},
+ },
+ },
+ want: ptr.To("the copy operation doesn't support a value attribute"),
+ },
+ {
+ name: "invalid operation",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("invalid")),
+ Path: ptr.To("/some/path"),
+ },
+ want: ptr.To("unsupported JSONPatch operation"),
+ },
+ {
+ name: "valid test operation",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("test")),
+ Path: ptr.To("/some/path"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte{},
+ },
+ },
+ },
+ {
+ name: "valid remove operation",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("remove")),
+ Path: ptr.To("/some/path"),
+ },
+ },
+ {
+ name: "valid copy operation",
+ input: JSONPatchOperation{
+ Op: TranslateJSONPatchOp(egv1a1.JSONPatchOperationType("copy")),
+ Path: ptr.To("/some/path"),
+ From: ptr.To("/some/other/path"),
+ },
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ err := tc.input.Validate()
+ if tc.want != nil {
+ require.EqualError(t, err, *tc.want)
+ } else {
+ require.NoError(t, err)
+ }
+ })
+ }
+}
diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go
index 273eeb1c3ca..0c734dbec70 100644
--- a/internal/ir/zz_generated.deepcopy.go
+++ b/internal/ir/zz_generated.deepcopy.go
@@ -25,6 +25,11 @@ func (in *ALSAccessLog) DeepCopyInto(out *ALSAccessLog) {
copy(*out, *in)
}
in.Destination.DeepCopyInto(&out.Destination)
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
if in.Text != nil {
in, out := &in.Text, &out.Text
*out = new(string)
@@ -42,6 +47,11 @@ func (in *ALSAccessLog) DeepCopyInto(out *ALSAccessLog) {
*out = new(ALSAccessLogHTTP)
(*in).DeepCopyInto(*out)
}
+ if in.LogType != nil {
+ in, out := &in.LogType, &out.LogType
+ *out = new(ProxyAccessLogType)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ALSAccessLog.
@@ -176,6 +186,11 @@ func (in *ActiveHealthCheck) DeepCopyInto(out *ActiveHealthCheck) {
*out = new(TCPHealthChecker)
(*in).DeepCopyInto(*out)
}
+ if in.GRPC != nil {
+ in, out := &in.GRPC, &out.GRPC
+ *out = new(GRPCHealthChecker)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ActiveHealthCheck.
@@ -191,6 +206,11 @@ func (in *ActiveHealthCheck) DeepCopy() *ActiveHealthCheck {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AddHeader) DeepCopyInto(out *AddHeader) {
*out = *in
+ if in.Value != nil {
+ in, out := &in.Value, &out.Value
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddHeader.
@@ -295,7 +315,7 @@ func (in *BasicAuth) DeepCopyInto(out *BasicAuth) {
*out = *in
if in.Users != nil {
in, out := &in.Users, &out.Users
- *out = make([]byte, len(*in))
+ *out = make(PrivateBytes, len(*in))
copy(*out, *in)
}
}
@@ -310,6 +330,21 @@ func (in *BasicAuth) DeepCopy() *BasicAuth {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BodyToExtAuth) DeepCopyInto(out *BodyToExtAuth) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BodyToExtAuth.
+func (in *BodyToExtAuth) DeepCopy() *BodyToExtAuth {
+ if in == nil {
+ return nil
+ }
+ out := new(BodyToExtAuth)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CORS) DeepCopyInto(out *CORS) {
*out = *in
@@ -531,6 +566,26 @@ func (in *ConsistentHash) DeepCopy() *ConsistentHash {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CookieBasedSessionPersistence) DeepCopyInto(out *CookieBasedSessionPersistence) {
+ *out = *in
+ if in.TTL != nil {
+ in, out := &in.TTL, &out.TTL
+ *out = new(v1.Duration)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CookieBasedSessionPersistence.
+func (in *CookieBasedSessionPersistence) DeepCopy() *CookieBasedSessionPersistence {
+ if in == nil {
+ return nil
+ }
+ out := new(CookieBasedSessionPersistence)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CoreListenerDetails) DeepCopyInto(out *CoreListenerDetails) {
*out = *in
@@ -550,6 +605,11 @@ func (in *CoreListenerDetails) DeepCopyInto(out *CoreListenerDetails) {
*out = new(ResourceMetadata)
(*in).DeepCopyInto(*out)
}
+ if in.IPFamily != nil {
+ in, out := &in.IPFamily, &out.IPFamily
+ *out = new(v1alpha1.IPFamily)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CoreListenerDetails.
@@ -562,6 +622,83 @@ func (in *CoreListenerDetails) DeepCopy() *CoreListenerDetails {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomResponse) DeepCopyInto(out *CustomResponse) {
+ *out = *in
+ if in.ContentType != nil {
+ in, out := &in.ContentType, &out.ContentType
+ *out = new(string)
+ **out = **in
+ }
+ if in.Body != nil {
+ in, out := &in.Body, &out.Body
+ *out = new(string)
+ **out = **in
+ }
+ if in.StatusCode != nil {
+ in, out := &in.StatusCode, &out.StatusCode
+ *out = new(uint32)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResponse.
+func (in *CustomResponse) DeepCopy() *CustomResponse {
+ if in == nil {
+ return nil
+ }
+ out := new(CustomResponse)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomResponseMatch) DeepCopyInto(out *CustomResponseMatch) {
+ *out = *in
+ if in.StatusCodes != nil {
+ in, out := &in.StatusCodes, &out.StatusCodes
+ *out = make([]StatusCodeMatch, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResponseMatch.
+func (in *CustomResponseMatch) DeepCopy() *CustomResponseMatch {
+ if in == nil {
+ return nil
+ }
+ out := new(CustomResponseMatch)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DNS) DeepCopyInto(out *DNS) {
+ *out = *in
+ if in.DNSRefreshRate != nil {
+ in, out := &in.DNSRefreshRate, &out.DNSRefreshRate
+ *out = new(v1.Duration)
+ **out = **in
+ }
+ if in.RespectDNSTTL != nil {
+ in, out := &in.RespectDNSTTL, &out.RespectDNSTTL
+ *out = new(bool)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNS.
+func (in *DNS) DeepCopy() *DNS {
+ if in == nil {
+ return nil
+ }
+ out := new(DNS)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DestinationEndpoint) DeepCopyInto(out *DestinationEndpoint) {
*out = *in
@@ -588,7 +725,9 @@ func (in *DestinationFilters) DeepCopyInto(out *DestinationFilters) {
if in.AddRequestHeaders != nil {
in, out := &in.AddRequestHeaders, &out.AddRequestHeaders
*out = make([]AddHeader, len(*in))
- copy(*out, *in)
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
if in.RemoveRequestHeaders != nil {
in, out := &in.RemoveRequestHeaders, &out.RemoveRequestHeaders
@@ -598,7 +737,9 @@ func (in *DestinationFilters) DeepCopyInto(out *DestinationFilters) {
if in.AddResponseHeaders != nil {
in, out := &in.AddResponseHeaders, &out.AddResponseHeaders
*out = make([]AddHeader, len(*in))
- copy(*out, *in)
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
if in.RemoveResponseHeaders != nil {
in, out := &in.RemoveResponseHeaders, &out.RemoveResponseHeaders
@@ -625,6 +766,11 @@ func (in *DestinationSetting) DeepCopyInto(out *DestinationSetting) {
*out = new(uint32)
**out = **in
}
+ if in.Priority != nil {
+ in, out := &in.Priority, &out.Priority
+ *out = new(uint32)
+ **out = **in
+ }
if in.Endpoints != nil {
in, out := &in.Endpoints, &out.Endpoints
*out = make([]*DestinationEndpoint, len(*in))
@@ -641,6 +787,11 @@ func (in *DestinationSetting) DeepCopyInto(out *DestinationSetting) {
*out = new(DestinationAddressType)
**out = **in
}
+ if in.IPFamily != nil {
+ in, out := &in.IPFamily, &out.IPFamily
+ *out = new(v1alpha1.IPFamily)
+ **out = **in
+ }
if in.TLS != nil {
in, out := &in.TLS, &out.TLS
*out = new(TLSUpstreamConfig)
@@ -663,21 +814,6 @@ func (in *DestinationSetting) DeepCopy() *DestinationSetting {
return out
}
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *DirectResponse) DeepCopyInto(out *DirectResponse) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DirectResponse.
-func (in *DirectResponse) DeepCopy() *DirectResponse {
- if in == nil {
- return nil
- }
- out := new(DirectResponse)
- in.DeepCopyInto(out)
- return out
-}
-
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EnvoyExtensionFeatures) DeepCopyInto(out *EnvoyExtensionFeatures) {
*out = *in
@@ -767,16 +903,31 @@ func (in *ExtAuth) DeepCopyInto(out *ExtAuth) {
*out = new(HTTPExtAuthService)
(*in).DeepCopyInto(*out)
}
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
if in.HeadersToExtAuth != nil {
in, out := &in.HeadersToExtAuth, &out.HeadersToExtAuth
*out = make([]string, len(*in))
copy(*out, *in)
}
+ if in.BodyToExtAuth != nil {
+ in, out := &in.BodyToExtAuth, &out.BodyToExtAuth
+ *out = new(BodyToExtAuth)
+ **out = **in
+ }
if in.FailOpen != nil {
in, out := &in.FailOpen, &out.FailOpen
*out = new(bool)
**out = **in
}
+ if in.RecomputeRoute != nil {
+ in, out := &in.RecomputeRoute, &out.RecomputeRoute
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtAuth.
@@ -793,6 +944,11 @@ func (in *ExtAuth) DeepCopy() *ExtAuth {
func (in *ExtProc) DeepCopyInto(out *ExtProc) {
*out = *in
in.Destination.DeepCopyInto(&out.Destination)
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
if in.MessageTimeout != nil {
in, out := &in.MessageTimeout, &out.MessageTimeout
*out = new(v1.Duration)
@@ -813,6 +969,16 @@ func (in *ExtProc) DeepCopyInto(out *ExtProc) {
*out = new(ExtProcBodyProcessingMode)
**out = **in
}
+ if in.RequestAttributes != nil {
+ in, out := &in.RequestAttributes, &out.RequestAttributes
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ if in.ResponseAttributes != nil {
+ in, out := &in.ResponseAttributes, &out.ResponseAttributes
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtProc.
@@ -825,6 +991,27 @@ func (in *ExtProc) DeepCopy() *ExtProc {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ExtendedHTTPPathModifier) DeepCopyInto(out *ExtendedHTTPPathModifier) {
+ *out = *in
+ in.HTTPPathModifier.DeepCopyInto(&out.HTTPPathModifier)
+ if in.RegexMatchReplace != nil {
+ in, out := &in.RegexMatchReplace, &out.RegexMatchReplace
+ *out = new(RegexMatchReplace)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtendedHTTPPathModifier.
+func (in *ExtendedHTTPPathModifier) DeepCopy() *ExtendedHTTPPathModifier {
+ if in == nil {
+ return nil
+ }
+ out := new(ExtendedHTTPPathModifier)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FaultInjection) DeepCopyInto(out *FaultInjection) {
*out = *in
@@ -921,6 +1108,26 @@ func (in *GRPCExtAuthService) DeepCopy() *GRPCExtAuthService {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GRPCHealthChecker) DeepCopyInto(out *GRPCHealthChecker) {
+ *out = *in
+ if in.Service != nil {
+ in, out := &in.Service, &out.Service
+ *out = new(string)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCHealthChecker.
+func (in *GRPCHealthChecker) DeepCopy() *GRPCHealthChecker {
+ if in == nil {
+ return nil
+ }
+ out := new(GRPCHealthChecker)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GlobalRateLimit) DeepCopyInto(out *GlobalRateLimit) {
*out = *in
@@ -1005,6 +1212,11 @@ func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) {
*out = new(uint32)
**out = **in
}
+ if in.ResetStreamOnError != nil {
+ in, out := &in.ResetStreamOnError, &out.ResetStreamOnError
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2Settings.
@@ -1093,6 +1305,36 @@ func (in *HTTPHealthChecker) DeepCopy() *HTTPHealthChecker {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HTTPHostModifier) DeepCopyInto(out *HTTPHostModifier) {
+ *out = *in
+ if in.Name != nil {
+ in, out := &in.Name, &out.Name
+ *out = new(string)
+ **out = **in
+ }
+ if in.Header != nil {
+ in, out := &in.Header, &out.Header
+ *out = new(string)
+ **out = **in
+ }
+ if in.Backend != nil {
+ in, out := &in.Backend, &out.Backend
+ *out = new(bool)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHostModifier.
+func (in *HTTPHostModifier) DeepCopy() *HTTPHostModifier {
+ if in == nil {
+ return nil
+ }
+ out := new(HTTPHostModifier)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HTTPListener) DeepCopyInto(out *HTTPListener) {
*out = *in
@@ -1234,7 +1476,9 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
if in.AddRequestHeaders != nil {
in, out := &in.AddRequestHeaders, &out.AddRequestHeaders
*out = make([]AddHeader, len(*in))
- copy(*out, *in)
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
if in.RemoveRequestHeaders != nil {
in, out := &in.RemoveRequestHeaders, &out.RemoveRequestHeaders
@@ -1244,7 +1488,9 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
if in.AddResponseHeaders != nil {
in, out := &in.AddResponseHeaders, &out.AddResponseHeaders
*out = make([]AddHeader, len(*in))
- copy(*out, *in)
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
if in.RemoveResponseHeaders != nil {
in, out := &in.RemoveResponseHeaders, &out.RemoveResponseHeaders
@@ -1253,8 +1499,8 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
}
if in.DirectResponse != nil {
in, out := &in.DirectResponse, &out.DirectResponse
- *out = new(DirectResponse)
- **out = **in
+ *out = new(CustomResponse)
+ (*in).DeepCopyInto(*out)
}
if in.Redirect != nil {
in, out := &in.Redirect, &out.Redirect
@@ -1318,6 +1564,16 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
*out = new(ResourceMetadata)
(*in).DeepCopyInto(*out)
}
+ if in.SessionPersistence != nil {
+ in, out := &in.SessionPersistence, &out.SessionPersistence
+ *out = new(SessionPersistence)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Timeout != nil {
+ in, out := &in.Timeout, &out.Timeout
+ *out = new(v1.Duration)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRoute.
@@ -1375,6 +1631,21 @@ func (in *HTTPWasmCode) DeepCopy() *HTTPWasmCode {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HeaderBasedSessionPersistence) DeepCopyInto(out *HeaderBasedSessionPersistence) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderBasedSessionPersistence.
+func (in *HeaderBasedSessionPersistence) DeepCopy() *HeaderBasedSessionPersistence {
+ if in == nil {
+ return nil
+ }
+ out := new(HeaderBasedSessionPersistence)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HeaderSettings) DeepCopyInto(out *HeaderSettings) {
*out = *in
@@ -1383,6 +1654,18 @@ func (in *HeaderSettings) DeepCopyInto(out *HeaderSettings) {
*out = new(XForwardedClientCert)
(*in).DeepCopyInto(*out)
}
+ if in.EarlyAddRequestHeaders != nil {
+ in, out := &in.EarlyAddRequestHeaders, &out.EarlyAddRequestHeaders
+ *out = make([]AddHeader, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.EarlyRemoveRequestHeaders != nil {
+ in, out := &in.EarlyRemoveRequestHeaders, &out.EarlyRemoveRequestHeaders
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderSettings.
@@ -1524,6 +1807,11 @@ func (in *JSONAccessLog) DeepCopyInto(out *JSONAccessLog) {
(*out)[key] = val
}
}
+ if in.LogType != nil {
+ in, out := &in.LogType, &out.LogType
+ *out = new(ProxyAccessLogType)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONAccessLog.
@@ -1555,6 +1843,16 @@ func (in *JSONPatchConfig) DeepCopy() *JSONPatchConfig {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONPatchOperation) DeepCopyInto(out *JSONPatchOperation) {
*out = *in
+ if in.Path != nil {
+ in, out := &in.Path, &out.Path
+ *out = new(string)
+ **out = **in
+ }
+ if in.JSONPath != nil {
+ in, out := &in.JSONPath, &out.JSONPath
+ *out = new(string)
+ **out = **in
+ }
if in.From != nil {
in, out := &in.From, &out.From
*out = new(string)
@@ -1714,15 +2012,15 @@ func (in *Metrics) DeepCopy() *Metrics {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OIDC) DeepCopyInto(out *OIDC) {
*out = *in
- out.Provider = in.Provider
+ in.Provider.DeepCopyInto(&out.Provider)
if in.ClientSecret != nil {
in, out := &in.ClientSecret, &out.ClientSecret
- *out = make([]byte, len(*in))
+ *out = make(PrivateBytes, len(*in))
copy(*out, *in)
}
if in.HMACSecret != nil {
in, out := &in.HMACSecret, &out.HMACSecret
- *out = make([]byte, len(*in))
+ *out = make(PrivateBytes, len(*in))
copy(*out, *in)
}
if in.Scopes != nil {
@@ -1750,6 +2048,11 @@ func (in *OIDC) DeepCopyInto(out *OIDC) {
*out = new(v1alpha1.OIDCCookieNames)
(*in).DeepCopyInto(*out)
}
+ if in.CookieDomain != nil {
+ in, out := &in.CookieDomain, &out.CookieDomain
+ *out = new(string)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDC.
@@ -1762,6 +2065,31 @@ func (in *OIDC) DeepCopy() *OIDC {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *OIDCProvider) DeepCopyInto(out *OIDCProvider) {
+ *out = *in
+ if in.Destination != nil {
+ in, out := &in.Destination, &out.Destination
+ *out = new(RouteDestination)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCProvider.
+func (in *OIDCProvider) DeepCopy() *OIDCProvider {
+ if in == nil {
+ return nil
+ }
+ out := new(OIDCProvider)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OpenTelemetryAccessLog) DeepCopyInto(out *OpenTelemetryAccessLog) {
*out = *in
@@ -1790,6 +2118,16 @@ func (in *OpenTelemetryAccessLog) DeepCopyInto(out *OpenTelemetryAccessLog) {
}
}
in.Destination.DeepCopyInto(&out.Destination)
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.LogType != nil {
+ in, out := &in.LogType, &out.LogType
+ *out = new(ProxyAccessLogType)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenTelemetryAccessLog.
@@ -1906,6 +2244,11 @@ func (in *Principal) DeepCopyInto(out *Principal) {
}
}
}
+ if in.JWT != nil {
+ in, out := &in.JWT, &out.JWT
+ *out = new(v1alpha1.JWTPrincipal)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Principal.
@@ -2131,6 +2474,21 @@ func (in *Redirect) DeepCopy() *Redirect {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *RegexMatchReplace) DeepCopyInto(out *RegexMatchReplace) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegexMatchReplace.
+func (in *RegexMatchReplace) DeepCopy() *RegexMatchReplace {
+ if in == nil {
+ return nil
+ }
+ out := new(RegexMatchReplace)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResourceMetadata) DeepCopyInto(out *ResourceMetadata) {
*out = *in
@@ -2153,6 +2511,45 @@ func (in *ResourceMetadata) DeepCopy() *ResourceMetadata {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ResponseOverride) DeepCopyInto(out *ResponseOverride) {
+ *out = *in
+ if in.Rules != nil {
+ in, out := &in.Rules, &out.Rules
+ *out = make([]ResponseOverrideRule, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResponseOverride.
+func (in *ResponseOverride) DeepCopy() *ResponseOverride {
+ if in == nil {
+ return nil
+ }
+ out := new(ResponseOverride)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ResponseOverrideRule) DeepCopyInto(out *ResponseOverrideRule) {
+ *out = *in
+ in.Match.DeepCopyInto(&out.Match)
+ in.Response.DeepCopyInto(&out.Response)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResponseOverrideRule.
+func (in *ResponseOverrideRule) DeepCopy() *ResponseOverrideRule {
+ if in == nil {
+ return nil
+ }
+ out := new(ResponseOverrideRule)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Retry) DeepCopyInto(out *Retry) {
*out = *in
@@ -2299,6 +2696,31 @@ func (in *SecurityFeatures) DeepCopy() *SecurityFeatures {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SessionPersistence) DeepCopyInto(out *SessionPersistence) {
+ *out = *in
+ if in.Cookie != nil {
+ in, out := &in.Cookie, &out.Cookie
+ *out = new(CookieBasedSessionPersistence)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Header != nil {
+ in, out := &in.Header, &out.Header
+ *out = new(HeaderBasedSessionPersistence)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SessionPersistence.
+func (in *SessionPersistence) DeepCopy() *SessionPersistence {
+ if in == nil {
+ return nil
+ }
+ out := new(SessionPersistence)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SlowStart) DeepCopyInto(out *SlowStart) {
*out = *in
@@ -2319,6 +2741,31 @@ func (in *SlowStart) DeepCopy() *SlowStart {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StatusCodeMatch) DeepCopyInto(out *StatusCodeMatch) {
+ *out = *in
+ if in.Value != nil {
+ in, out := &in.Value, &out.Value
+ *out = new(int)
+ **out = **in
+ }
+ if in.Range != nil {
+ in, out := &in.Range, &out.Range
+ *out = new(StatusCodeRange)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusCodeMatch.
+func (in *StatusCodeMatch) DeepCopy() *StatusCodeMatch {
+ if in == nil {
+ return nil
+ }
+ out := new(StatusCodeMatch)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StringMatch) DeepCopyInto(out *StringMatch) {
*out = *in
@@ -2342,6 +2789,11 @@ func (in *StringMatch) DeepCopyInto(out *StringMatch) {
*out = new(string)
**out = **in
}
+ if in.Invert != nil {
+ in, out := &in.Invert, &out.Invert
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StringMatch.
@@ -2524,6 +2976,11 @@ func (in *TCPRoute) DeepCopyInto(out *TCPRoute) {
*out = new(BackendConnection)
(*in).DeepCopyInto(*out)
}
+ if in.DNS != nil {
+ in, out := &in.DNS, &out.DNS
+ *out = new(DNS)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPRoute.
@@ -2611,7 +3068,7 @@ func (in *TLSCertificate) DeepCopyInto(out *TLSCertificate) {
}
if in.PrivateKey != nil {
in, out := &in.PrivateKey, &out.PrivateKey
- *out = make([]byte, len(*in))
+ *out = make(PrivateBytes, len(*in))
copy(*out, *in)
}
}
@@ -2744,6 +3201,11 @@ func (in *TextAccessLog) DeepCopyInto(out *TextAccessLog) {
*out = new(string)
**out = **in
}
+ if in.LogType != nil {
+ in, out := &in.LogType, &out.LogType
+ *out = new(ProxyAccessLogType)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TextAccessLog.
@@ -2792,6 +3254,11 @@ func (in *Tracing) DeepCopyInto(out *Tracing) {
}
}
in.Destination.DeepCopyInto(&out.Destination)
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
in.Provider.DeepCopyInto(&out.Provider)
}
@@ -2858,6 +3325,21 @@ func (in *TrafficFeatures) DeepCopyInto(out *TrafficFeatures) {
*out = new(BackendConnection)
(*in).DeepCopyInto(*out)
}
+ if in.HTTP2 != nil {
+ in, out := &in.HTTP2, &out.HTTP2
+ *out = new(HTTP2Settings)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.DNS != nil {
+ in, out := &in.DNS, &out.DNS
+ *out = new(DNS)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.ResponseOverride != nil {
+ in, out := &in.ResponseOverride, &out.ResponseOverride
+ *out = new(ResponseOverride)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficFeatures.
@@ -2904,14 +3386,9 @@ func (in *UDPRoute) DeepCopyInto(out *UDPRoute) {
*out = new(LoadBalancer)
(*in).DeepCopyInto(*out)
}
- if in.Timeout != nil {
- in, out := &in.Timeout, &out.Timeout
- *out = new(Timeout)
- (*in).DeepCopyInto(*out)
- }
- if in.BackendConnection != nil {
- in, out := &in.BackendConnection, &out.BackendConnection
- *out = new(BackendConnection)
+ if in.DNS != nil {
+ in, out := &in.DNS, &out.DNS
+ *out = new(DNS)
(*in).DeepCopyInto(*out)
}
}
@@ -2931,13 +3408,13 @@ func (in *URLRewrite) DeepCopyInto(out *URLRewrite) {
*out = *in
if in.Path != nil {
in, out := &in.Path, &out.Path
- *out = new(HTTPPathModifier)
+ *out = new(ExtendedHTTPPathModifier)
(*in).DeepCopyInto(*out)
}
- if in.Hostname != nil {
- in, out := &in.Hostname, &out.Hostname
- *out = new(string)
- **out = **in
+ if in.Host != nil {
+ in, out := &in.Host, &out.Host
+ *out = new(HTTPHostModifier)
+ (*in).DeepCopyInto(*out)
}
}
@@ -2988,6 +3465,11 @@ func (in *Wasm) DeepCopyInto(out *Wasm) {
*out = new(HTTPWasmCode)
**out = **in
}
+ if in.HostKeys != nil {
+ in, out := &in.HostKeys, &out.HostKeys
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Wasm.
diff --git a/internal/kubernetes/port_forwarder.go b/internal/kubernetes/port_forwarder.go
index 176610dab3e..8e88b9c0212 100644
--- a/internal/kubernetes/port_forwarder.go
+++ b/internal/kubernetes/port_forwarder.go
@@ -8,8 +8,10 @@ package kubernetes
import (
"fmt"
"io"
+ "net"
"net/http"
"os"
+ "strconv"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/rest"
@@ -134,5 +136,5 @@ func (f *localForwarder) WaitForStop() {
}
func (f *localForwarder) Address() string {
- return fmt.Sprintf("%s:%d", netutil.DefaultLocalAddress, f.localPort)
+ return net.JoinHostPort(netutil.DefaultLocalAddress, strconv.Itoa(f.localPort))
}
diff --git a/internal/kubernetes/secret.go b/internal/kubernetes/secret.go
index ff98d61874b..f2774dce4d8 100644
--- a/internal/kubernetes/secret.go
+++ b/internal/kubernetes/secret.go
@@ -15,13 +15,13 @@ import (
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
- "github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
)
// ValidateSecretObjectReference validate secret object reference for extension tls and ratelimit tls settings.
func ValidateSecretObjectReference(ctx context.Context, client k8sclient.Client, secretObjRef *gwapiv1.SecretObjectReference, namespace string) (*corev1.Secret, string, error) {
if (secretObjRef.Group == nil || *secretObjRef.Group == corev1.GroupName) &&
- (secretObjRef.Kind == nil || *secretObjRef.Kind == gatewayapi.KindSecret) {
+ (secretObjRef.Kind == nil || *secretObjRef.Kind == resource.KindSecret) {
secret := &corev1.Secret{}
secretNamespace := namespace
if secretObjRef.Namespace != nil && string(*secretObjRef.Namespace) != "" {
diff --git a/internal/logging/log.go b/internal/logging/log.go
index a4fb787f9c2..274f11f05a4 100644
--- a/internal/logging/log.go
+++ b/internal/logging/log.go
@@ -72,7 +72,7 @@ func (l Logger) WithName(name string) Logger {
return Logger{
Logger: zapr.NewLogger(logger).WithName(name),
logging: l.logging,
- sugaredLogger: logger.Sugar(),
+ sugaredLogger: logger.Sugar().Named(name),
}
}
diff --git a/internal/logging/log_test.go b/internal/logging/log_test.go
index 999f922759c..0942910f71c 100644
--- a/internal/logging/log_test.go
+++ b/internal/logging/log_test.go
@@ -75,3 +75,32 @@ func TestLoggerWithName(t *testing.T) {
assert.Contains(t, capturedOutput, "info message")
assert.Contains(t, capturedOutput, "debug message")
}
+
+func TestLoggerSugarName(t *testing.T) {
+ originalStdout := os.Stdout
+ r, w, _ := os.Pipe()
+ os.Stdout = w
+
+ defer func() {
+ // Restore the original stdout and close the pipe
+ os.Stdout = originalStdout
+ err := w.Close()
+ require.NoError(t, err)
+ }()
+
+ const logName = "loggerName"
+
+ config := egv1a1.DefaultEnvoyGatewayLogging()
+ config.Level[logName] = egv1a1.LogLevelDebug
+
+ logger := NewLogger(config).WithName(logName)
+
+ logger.Sugar().Debugf("debugging message")
+
+ // Read from the pipe (captured stdout)
+ outputBytes := make([]byte, 200)
+ _, err := r.Read(outputBytes)
+ require.NoError(t, err)
+ capturedOutput := string(outputBytes)
+ assert.Contains(t, capturedOutput, "debugging message", logName)
+}
diff --git a/internal/message/metrics.go b/internal/message/metrics.go
index 5f120124191..de744f47aa8 100644
--- a/internal/message/metrics.go
+++ b/internal/message/metrics.go
@@ -13,6 +13,11 @@ var (
"Current depth of watchable queue.",
)
+ panicCounter = metrics.NewCounter(
+ "watchable_panics_recovered_total",
+ "Total number of panics recovered while handling items in queue.",
+ )
+
watchableSubscribeDurationSeconds = metrics.NewHistogram(
"watchable_subscribe_duration_seconds",
"How long in seconds a subscribed watchable queue is handled.",
diff --git a/internal/message/types.go b/internal/message/types.go
index fb82aa1401a..2eee7f90345 100644
--- a/internal/message/types.go
+++ b/internal/message/types.go
@@ -12,7 +12,8 @@ import (
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
- "github.com/envoyproxy/gateway/internal/gatewayapi"
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/ir"
xdstypes "github.com/envoyproxy/gateway/internal/xds/types"
)
@@ -21,7 +22,7 @@ import (
type ProviderResources struct {
// GatewayAPIResources is a map from a GatewayClass name to
// a group of gateway API and other related resources.
- GatewayAPIResources watchable.Map[string, *gatewayapi.ControllerResources]
+ GatewayAPIResources watchable.Map[string, *resource.ControllerResources]
// GatewayAPIStatuses is a group of gateway api
// resource statuses maps.
@@ -29,9 +30,12 @@ type ProviderResources struct {
// PolicyStatuses is a group of policy statuses maps.
PolicyStatuses
+
+ // ExtensionStatuses is a group of gw-api extension resource statuses map.
+ ExtensionStatuses
}
-func (p *ProviderResources) GetResources() []*gatewayapi.Resources {
+func (p *ProviderResources) GetResources() []*resource.Resources {
if p.GatewayAPIResources.Len() == 0 {
return nil
}
@@ -43,7 +47,7 @@ func (p *ProviderResources) GetResources() []*gatewayapi.Resources {
return nil
}
-func (p *ProviderResources) GetResourcesByGatewayClass(name string) *gatewayapi.Resources {
+func (p *ProviderResources) GetResourcesByGatewayClass(name string) *resource.Resources {
for _, r := range p.GetResources() {
if r != nil && r.GatewayClass != nil && r.GatewayClass.Name == name {
return r
@@ -71,12 +75,13 @@ func (p *ProviderResources) Close() {
// GatewayAPIStatuses contains gateway API resources statuses
type GatewayAPIStatuses struct {
- GatewayStatuses watchable.Map[types.NamespacedName, *gwapiv1.GatewayStatus]
- HTTPRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1.HTTPRouteStatus]
- GRPCRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1.GRPCRouteStatus]
- TLSRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1a2.TLSRouteStatus]
- TCPRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1a2.TCPRouteStatus]
- UDPRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1a2.UDPRouteStatus]
+ GatewayClassStatuses watchable.Map[types.NamespacedName, *gwapiv1.GatewayClassStatus]
+ GatewayStatuses watchable.Map[types.NamespacedName, *gwapiv1.GatewayStatus]
+ HTTPRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1.HTTPRouteStatus]
+ GRPCRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1.GRPCRouteStatus]
+ TLSRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1a2.TLSRouteStatus]
+ TCPRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1a2.TCPRouteStatus]
+ UDPRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1a2.UDPRouteStatus]
}
func (s *GatewayAPIStatuses) Close() {
@@ -104,6 +109,11 @@ type PolicyStatuses struct {
ExtensionPolicyStatuses watchable.Map[NamespacedNameAndGVK, *gwapiv1a2.PolicyStatus]
}
+// ExtensionStatuses contains statuses related to gw-api extension resources
+type ExtensionStatuses struct {
+ BackendStatuses watchable.Map[types.NamespacedName, *egv1a1.BackendStatus]
+}
+
func (p *PolicyStatuses) Close() {
p.ClientTrafficPolicyStatuses.Close()
p.SecurityPolicyStatuses.Close()
diff --git a/internal/message/watchutil.go b/internal/message/watchutil.go
index f8391cbc47a..77caa4af3d9 100644
--- a/internal/message/watchutil.go
+++ b/internal/message/watchutil.go
@@ -6,6 +6,8 @@
package message
import (
+ "fmt"
+ "runtime/debug"
"time"
"github.com/telepresenceio/watchable"
@@ -36,6 +38,28 @@ func (m Metadata) LabelValues() []metrics.LabelValue {
return labels
}
+// handleWithCrashRecovery calls the provided handle function and gracefully recovers from any panics
+// that might occur when the handle function is called.
+func handleWithCrashRecovery[K comparable, V any](
+ handle func(updateFunc Update[K, V], errChans chan error),
+ update Update[K, V],
+ meta Metadata,
+ errChans chan error,
+) {
+ defer func() {
+ if r := recover(); r != nil {
+ logger.WithValues("runner", meta.Runner).Error(fmt.Errorf("%+v", r), "observed a panic",
+ "stackTrace", string(debug.Stack()))
+ watchableSubscribeTotal.WithFailure(metrics.ReasonError, meta.LabelValues()...).Increment()
+ panicCounter.WithFailure(metrics.ReasonError, meta.LabelValues()...).Increment()
+ }
+ }()
+ startHandleTime := time.Now()
+ handle(update, errChans)
+ watchableSubscribeTotal.WithSuccess(meta.LabelValues()...).Increment()
+ watchableSubscribeDurationSeconds.With(meta.LabelValues()...).Record(time.Since(startHandleTime).Seconds())
+}
+
// HandleSubscription takes a channel returned by
// watchable.Map.Subscribe() (or .SubscribeSubset()), and calls the
// given function for each initial value in the map, and for any
@@ -57,25 +81,20 @@ func HandleSubscription[K comparable, V any](
watchableSubscribeTotal.WithFailure(metrics.ReasonError, meta.LabelValues()...).Increment()
}
}()
+ defer close(errChans)
if snapshot, ok := <-subscription; ok {
for k, v := range snapshot.State {
- startHandleTime := time.Now()
- handle(Update[K, V]{
+ handleWithCrashRecovery(handle, Update[K, V]{
Key: k,
Value: v,
- }, errChans)
- watchableSubscribeTotal.WithSuccess(meta.LabelValues()...).Increment()
- watchableSubscribeDurationSeconds.With(meta.LabelValues()...).Record(time.Since(startHandleTime).Seconds())
+ }, meta, errChans)
}
}
for snapshot := range subscription {
watchableDepth.With(meta.LabelValues()...).Record(float64(len(subscription)))
for _, update := range snapshot.Updates {
- startHandleTime := time.Now()
- handle(Update[K, V](update), errChans)
- watchableSubscribeTotal.WithSuccess(meta.LabelValues()...).Increment()
- watchableSubscribeDurationSeconds.With(meta.LabelValues()...).Record(time.Since(startHandleTime).Seconds())
+ handleWithCrashRecovery(handle, Update[K, V](update), meta, errChans)
}
}
}
diff --git a/internal/message/watchutil_test.go b/internal/message/watchutil_test.go
index 2c08821b211..6e6472d14f0 100644
--- a/internal/message/watchutil_test.go
+++ b/internal/message/watchutil_test.go
@@ -30,6 +30,34 @@ func TestHandleSubscriptionAlreadyClosed(t *testing.T) {
assert.Equal(t, 0, calls)
}
+func TestPanicInSubscriptionHandler(t *testing.T) {
+ defer func() {
+ if r := recover(); r != nil {
+ assert.Fail(t, "recovered from an unexpected panic")
+ }
+ }()
+ var m watchable.Map[string, any]
+ m.Store("foo", "bar")
+
+ go func() {
+ time.Sleep(100 * time.Millisecond)
+ m.Store("baz", "qux")
+ time.Sleep(100 * time.Millisecond)
+ m.Close()
+ }()
+
+ numCalls := 0
+ message.HandleSubscription[string, any](
+ message.Metadata{Runner: "demo", Message: "demo"},
+ m.Subscribe(context.Background()),
+ func(update message.Update[string, any], errChans chan error) {
+ numCalls++
+ panic("oops " + update.Key)
+ },
+ )
+ assert.Equal(t, 2, numCalls)
+}
+
func TestHandleSubscriptionAlreadyInitialized(t *testing.T) {
var m watchable.Map[string, any]
m.Store("foo", "bar")
diff --git a/internal/metrics/metadata.go b/internal/metrics/metadata.go
index c6daf9e94da..5b5fd045d52 100644
--- a/internal/metrics/metadata.go
+++ b/internal/metrics/metadata.go
@@ -12,21 +12,10 @@ import (
"go.opentelemetry.io/otel"
api "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/sdk/metric"
-
- egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
- log "github.com/envoyproxy/gateway/internal/logging"
-)
-
-var (
- meter = func() api.Meter {
- return otel.GetMeterProvider().Meter("envoy-gateway")
- }
-
- metricsLogger = log.DefaultLogger(egv1a1.LogLevelInfo).WithName("metrics")
)
-func init() {
- otel.SetLogger(metricsLogger.Logger)
+var meter = func() api.Meter {
+ return otel.GetMeterProvider().Meter("envoy-gateway")
}
// MetricType is the type of a metric.
@@ -56,7 +45,7 @@ type Metadata struct {
Bounds []float64
}
-// metrics stores stores metrics
+// metrics stores metrics
type store struct {
started bool
mu sync.Mutex
diff --git a/internal/metrics/metrics_test.go b/internal/metrics/metrics_test.go
index 9b1aafcd5e2..55b682aff79 100644
--- a/internal/metrics/metrics_test.go
+++ b/internal/metrics/metrics_test.go
@@ -16,6 +16,7 @@ import (
"os"
"reflect"
"strings"
+ "sync"
"testing"
"time"
@@ -95,24 +96,7 @@ func TestGauge(t *testing.T) {
// simulate a function that builds an indicator and changes its value
metricsFunc := []func(){
- func() {
- metricName := "current_irs_queue_num"
- description := "current number of ir in queue, by ir type"
-
- currentIRsNum := NewGauge(
- metricName,
- description,
- )
-
- // only the last recorded value (2) will be exported for this gauge
- currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(1)
- currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(3)
- currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(2)
-
- currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(1)
- currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(3)
- currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(2)
- },
+ metricFunc,
}
for _, f := range metricsFunc {
f()
@@ -125,6 +109,25 @@ func TestGauge(t *testing.T) {
loadMetricsFile(t, name, writer)
}
+func metricFunc() {
+ metricName := "current_irs_queue_num"
+ description := "current number of ir in queue, by ir type"
+
+ currentIRsNum := NewGauge(
+ metricName,
+ description,
+ )
+
+ // only the last recorded value (2) will be exported for this gauge
+ currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(1)
+ currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(3)
+ currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(2)
+
+ currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(1)
+ currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(3)
+ currentIRsNum.With(NewLabel("ir-type").Value("xds")).Record(2)
+}
+
func TestHistogram(t *testing.T) {
name := "histogram_metric"
@@ -165,6 +168,22 @@ func TestHistogram(t *testing.T) {
loadMetricsFile(t, name, writer)
}
+func TestConcurrentMetricAccess(t *testing.T) {
+ var wg sync.WaitGroup
+ const concurrency = 100
+
+ for i := 0; i < concurrency; i++ {
+ wg.Add(1)
+ go func(idx int) {
+ defer wg.Done()
+ t.Logf("concurrency metric access at %d", idx)
+ metricFunc()
+ }(i)
+ }
+
+ wg.Wait()
+}
+
// newTestMetricsProvider Create an OTEL Metrics Provider for testing use only
func newTestMetricsProvider(metricType string, writer io.Writer) (*metric.MeterProvider, error) {
enc := json.NewEncoder(writer)
diff --git a/internal/metrics/otel_label.go b/internal/metrics/otel_label.go
index bcf4c472209..8c4c54c339c 100644
--- a/internal/metrics/otel_label.go
+++ b/internal/metrics/otel_label.go
@@ -58,8 +58,7 @@ func mergeLabelValues(attrs []attribute.KeyValue, labelValues []LabelValue) ([]a
mergedAttrs := make([]attribute.KeyValue, 0, len(attrs)+len(labelValues))
mergedAttrs = append(mergedAttrs, attrs...)
for _, v := range labelValues {
- kv := v
- mergedAttrs = append(mergedAttrs, kv.keyValue)
+ mergedAttrs = append(mergedAttrs, v.keyValue)
}
return mergedAttrs, attribute.NewSet(mergedAttrs...)
diff --git a/internal/metrics/otel_metric_gauge.go b/internal/metrics/otel_metric_gauge.go
index 49e02395b67..7fe0ac3dc5d 100644
--- a/internal/metrics/otel_metric_gauge.go
+++ b/internal/metrics/otel_metric_gauge.go
@@ -29,15 +29,19 @@ type GaugeValues struct {
func (f *Gauge) Record(value float64) {
f.mutex.Lock()
+ defer f.mutex.Unlock()
+
if f.current == nil {
f.current = &GaugeValues{}
f.stores[attribute.NewSet()] = f.current
}
f.current.val = value
- f.mutex.Unlock()
}
func (f *Gauge) With(labelValues ...LabelValue) *Gauge {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
attrs, set := mergeLabelValues(f.attrs, labelValues)
m := &Gauge{
g: f.g,
diff --git a/internal/metrics/register.go b/internal/metrics/register.go
index f4e9e7a34cc..1f4c0a483f0 100644
--- a/internal/metrics/register.go
+++ b/internal/metrics/register.go
@@ -23,14 +23,20 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
+ log "github.com/envoyproxy/gateway/internal/logging"
)
const (
defaultEndpoint = "/metrics"
)
+var metricsLogger log.Logger
+
// Init initializes and registers the global metrics server.
func Init(cfg *config.Server) error {
+ metricsLogger = cfg.Logger.WithName("metrics")
+ otel.SetLogger(metricsLogger.Logger)
+
options, err := newOptions(cfg)
if err != nil {
return err
diff --git a/internal/metrics/testdata/counter_metric.json b/internal/metrics/testdata/counter_metric.json
index 2c1859a3d45..62b17ac82e1 100644
--- a/internal/metrics/testdata/counter_metric.json
+++ b/internal/metrics/testdata/counter_metric.json
@@ -20,7 +20,8 @@
"Scope": {
"Name": "envoy-gateway",
"Version": "",
- "SchemaURL": ""
+ "SchemaURL": "",
+ "Attributes": null
},
"Metrics": [
{
diff --git a/internal/metrics/testdata/gauge_metric.json b/internal/metrics/testdata/gauge_metric.json
index 7641f17cbee..976d5cf3e40 100644
--- a/internal/metrics/testdata/gauge_metric.json
+++ b/internal/metrics/testdata/gauge_metric.json
@@ -20,7 +20,8 @@
"Scope": {
"Name": "envoy-gateway",
"Version": "",
- "SchemaURL": ""
+ "SchemaURL": "",
+ "Attributes": null
},
"Metrics": [
{
diff --git a/internal/metrics/testdata/histogram_metric.json b/internal/metrics/testdata/histogram_metric.json
index 0054be03640..70571a68f2e 100644
--- a/internal/metrics/testdata/histogram_metric.json
+++ b/internal/metrics/testdata/histogram_metric.json
@@ -20,7 +20,8 @@
"Scope": {
"Name": "envoy-gateway",
"Version": "",
- "SchemaURL": ""
+ "SchemaURL": "",
+ "Attributes": null
},
"Metrics": [
{
diff --git a/internal/provider/file/file.go b/internal/provider/file/file.go
new file mode 100644
index 00000000000..22452772fa2
--- /dev/null
+++ b/internal/provider/file/file.go
@@ -0,0 +1,207 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package file
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync/atomic"
+ "time"
+
+ "github.com/fsnotify/fsnotify"
+ "github.com/go-logr/logr"
+ "k8s.io/apimachinery/pkg/util/sets"
+ "sigs.k8s.io/controller-runtime/pkg/healthz"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/filewatcher"
+ "github.com/envoyproxy/gateway/internal/message"
+ "github.com/envoyproxy/gateway/internal/utils/path"
+)
+
+type Provider struct {
+ paths []string
+ logger logr.Logger
+ watcher filewatcher.FileWatcher
+ resourcesStore *resourcesStore
+
+ // ready indicates whether the provider can start watching filesystem events.
+ ready atomic.Bool
+}
+
+func New(svr *config.Server, resources *message.ProviderResources) (*Provider, error) {
+ logger := svr.Logger.Logger
+ paths := sets.New[string]()
+ if svr.EnvoyGateway.Provider.Custom.Resource.File != nil {
+ paths.Insert(svr.EnvoyGateway.Provider.Custom.Resource.File.Paths...)
+ }
+
+ return &Provider{
+ paths: paths.UnsortedList(),
+ logger: logger,
+ watcher: filewatcher.NewWatcher(),
+ resourcesStore: newResourcesStore(svr.EnvoyGateway.Gateway.ControllerName, resources, logger),
+ }, nil
+}
+
+func (p *Provider) Type() egv1a1.ProviderType {
+ return egv1a1.ProviderTypeCustom
+}
+
+func (p *Provider) Start(ctx context.Context) error {
+ defer func() {
+ _ = p.watcher.Close()
+ }()
+
+ // Start runnable servers.
+ var readyzChecker healthz.Checker = func(req *http.Request) error {
+ if !p.ready.Load() {
+ return fmt.Errorf("file provider not ready yet")
+ }
+ return nil
+ }
+ go p.startHealthProbeServer(ctx, readyzChecker)
+
+ initDirs, initFiles := path.ListDirsAndFiles(p.paths)
+ // Initially load resources from paths on host.
+ if err := p.resourcesStore.LoadAndStore(initFiles.UnsortedList(), initDirs.UnsortedList()); err != nil {
+ return fmt.Errorf("failed to load resources into store: %w", err)
+ }
+
+ // Add paths to the watcher, and aggregate all path channels into one.
+ aggCh := make(chan fsnotify.Event)
+ for _, path := range p.paths {
+ if err := p.watcher.Add(path); err != nil {
+ p.logger.Error(err, "failed to add watch", "path", path)
+ } else {
+ p.logger.Info("Watching path added", "path", path)
+ }
+
+ ch := p.watcher.Events(path)
+ go func(c chan fsnotify.Event) {
+ for msg := range c {
+ aggCh <- msg
+ }
+ }(ch)
+ }
+
+ p.ready.Store(true)
+ curDirs, curFiles := initDirs.Clone(), initFiles.Clone()
+ initFilesParent := path.GetParentDirs(initFiles.UnsortedList())
+ for {
+ select {
+ case <-ctx.Done():
+ return nil
+ case event := <-aggCh:
+ // Ignore the irrelevant event.
+ if event.Has(fsnotify.Chmod) {
+ continue
+ }
+
+ // If a file change event is detected, regardless of the event type, it will be processed
+ // as a Remove event if the file does not exist, and as a Write event if the file exists.
+ //
+ // The reason to do so is quite straightforward, for text edit tools like vi/vim etc.
+ // They always create a temporary file, remove the existing one and replace it with the
+ // temporary file when file is saved. So the watcher will only receive:
+ // - Create event, with name "filename~".
+ // - Remove event, with name "filename", but the file actually exist.
+ if initFilesParent.Has(filepath.Dir(event.Name)) {
+ p.logger.Info("file changed", "op", event.Op, "name", event.Name)
+
+ // For Write event, the file definitely exist.
+ if initFiles.Has(event.Name) && event.Has(fsnotify.Write) {
+ goto handle
+ }
+
+ // Iter over the watched files to see the different.
+ for f := range initFiles {
+ _, err := os.Lstat(f)
+ if err != nil {
+ if os.IsNotExist(err) {
+ curFiles.Delete(f)
+ } else {
+ p.logger.Error(err, "stat file error", "name", f)
+ }
+ } else {
+ curFiles.Insert(f)
+ }
+ }
+ goto handle
+ }
+
+ // Ignore the hidden or temporary file related change event under a directory.
+ if _, name := filepath.Split(event.Name); strings.HasPrefix(name, ".") || strings.HasSuffix(name, "~") {
+ continue
+ }
+ p.logger.Info("file changed", "op", event.Op, "name", event.Name, "dir", filepath.Dir(event.Name))
+
+ switch event.Op {
+ case fsnotify.Create, fsnotify.Write, fsnotify.Remove:
+ // Since we do not watch any events in the subdirectories, any events involving files
+ // modifications in current directory will trigger the event handling.
+ goto handle
+ default:
+ // do nothing
+ continue
+ }
+
+ handle:
+ p.resourcesStore.HandleEvent(curFiles.UnsortedList(), curDirs.UnsortedList())
+ }
+ }
+}
+
+func (p *Provider) startHealthProbeServer(ctx context.Context, readyzChecker healthz.Checker) {
+ const (
+ readyzEndpoint = "/readyz"
+ healthzEndpoint = "/healthz"
+ )
+
+ mux := http.NewServeMux()
+ srv := &http.Server{
+ Addr: ":8081",
+ Handler: mux,
+ MaxHeaderBytes: 1 << 20,
+ IdleTimeout: 90 * time.Second, // matches http.DefaultTransport keep-alive timeout
+ ReadHeaderTimeout: 32 * time.Second,
+ }
+
+ readyzHandler := &healthz.Handler{
+ Checks: map[string]healthz.Checker{
+ readyzEndpoint: readyzChecker,
+ },
+ }
+ mux.Handle(readyzEndpoint, http.StripPrefix(readyzEndpoint, readyzHandler))
+ // Append '/' suffix to handle subpaths.
+ mux.Handle(readyzEndpoint+"/", http.StripPrefix(readyzEndpoint, readyzHandler))
+
+ healthzHandler := &healthz.Handler{
+ Checks: map[string]healthz.Checker{
+ healthzEndpoint: healthz.Ping,
+ },
+ }
+ mux.Handle(healthzEndpoint, http.StripPrefix(healthzEndpoint, healthzHandler))
+ // Append '/' suffix to handle subpaths.
+ mux.Handle(healthzEndpoint+"/", http.StripPrefix(healthzEndpoint, readyzHandler))
+
+ go func() {
+ <-ctx.Done()
+ if err := srv.Close(); err != nil {
+ p.logger.Error(err, "failed to close health probe server")
+ }
+ }()
+
+ p.logger.Info("starting health probe server", "address", srv.Addr)
+ if err := srv.ListenAndServe(); err != nil {
+ p.logger.Error(err, "failed to start health probe server")
+ }
+}
diff --git a/internal/provider/file/file_test.go b/internal/provider/file/file_test.go
new file mode 100644
index 00000000000..8f681d47d54
--- /dev/null
+++ b/internal/provider/file/file_test.go
@@ -0,0 +1,225 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package file
+
+import (
+ "context"
+ "html/template"
+ "io"
+ "net/http"
+ "os"
+ "path/filepath"
+ "testing"
+ "time"
+
+ "github.com/google/go-cmp/cmp"
+ "github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/stretchr/testify/require"
+ "sigs.k8s.io/yaml"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
+ "github.com/envoyproxy/gateway/internal/message"
+)
+
+const (
+ resourcesUpdateTimeout = 1 * time.Minute
+ resourcesUpdateTick = 1 * time.Second
+)
+
+type resourcesParam struct {
+ GatewayClassName string
+ GatewayName string
+ GatewayListenerPort string
+ HTTPRouteName string
+ BackendName string
+}
+
+func newDefaultResourcesParam() *resourcesParam {
+ return &resourcesParam{
+ GatewayClassName: "eg",
+ GatewayName: "eg",
+ GatewayListenerPort: "8888",
+ HTTPRouteName: "backend",
+ BackendName: "backend",
+ }
+}
+
+func newFileProviderConfig(paths []string) (*config.Server, error) {
+ cfg, err := config.New()
+ if err != nil {
+ return nil, err
+ }
+
+ cfg.EnvoyGateway.Provider = &egv1a1.EnvoyGatewayProvider{
+ Type: egv1a1.ProviderTypeCustom,
+ Custom: &egv1a1.EnvoyGatewayCustomProvider{
+ Resource: egv1a1.EnvoyGatewayResourceProvider{
+ Type: egv1a1.ResourceProviderTypeFile,
+ File: &egv1a1.EnvoyGatewayFileResourceProvider{
+ Paths: paths,
+ },
+ },
+ },
+ }
+ return cfg, nil
+}
+
+func TestFileProvider(t *testing.T) {
+ watchFileBase, _ := os.MkdirTemp(os.TempDir(), "test-files-*")
+ watchFilePath := filepath.Join(watchFileBase, "test.yaml")
+ watchDirPath, _ := os.MkdirTemp(os.TempDir(), "test-dir-*")
+ // Prepare the watched test file.
+ writeResourcesFile(t, "testdata/resources.tmpl", watchFilePath, newDefaultResourcesParam())
+ require.FileExists(t, watchFilePath)
+ require.DirExists(t, watchDirPath)
+
+ cfg, err := newFileProviderConfig([]string{watchFilePath, watchDirPath})
+ require.NoError(t, err)
+ pResources := new(message.ProviderResources)
+ fp, err := New(cfg, pResources)
+ require.NoError(t, err)
+ // Start file provider.
+ go func() {
+ if err := fp.Start(context.Background()); err != nil {
+ t.Errorf("failed to start file provider: %v", err)
+ }
+ }()
+
+ // Wait for file provider to be ready.
+ waitFileProviderReady(t)
+
+ require.Equal(t, "gateway.envoyproxy.io/gatewayclass-controller", fp.resourcesStore.name)
+
+ t.Run("initial resource load", func(t *testing.T) {
+ require.NotZero(t, pResources.GatewayAPIResources.Len())
+ resources := pResources.GetResourcesByGatewayClass("eg")
+ require.NotNil(t, resources)
+
+ want := &resource.Resources{}
+ mustUnmarshal(t, "testdata/resources.all.yaml", want)
+
+ opts := []cmp.Option{
+ cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"),
+ cmpopts.EquateEmpty(),
+ }
+ require.Empty(t, cmp.Diff(want, resources, opts...))
+ })
+
+ t.Run("rename the watched file then rename it back", func(t *testing.T) {
+ // Rename it
+ renameFilePath := filepath.Join(watchFileBase, "foobar.yaml")
+ err := os.Rename(watchFilePath, renameFilePath)
+ require.NoError(t, err)
+ require.Eventually(t, func() bool {
+ return pResources.GetResourcesByGatewayClass("eg") == nil
+ }, resourcesUpdateTimeout, resourcesUpdateTick)
+
+ // Rename it back
+ err = os.Rename(renameFilePath, watchFilePath)
+ require.NoError(t, err)
+ require.Eventually(t, func() bool {
+ return pResources.GetResourcesByGatewayClass("eg") != nil
+ }, resourcesUpdateTimeout, resourcesUpdateTick)
+
+ resources := pResources.GetResourcesByGatewayClass("eg")
+ want := &resource.Resources{}
+ mustUnmarshal(t, "testdata/resources.all.yaml", want)
+
+ opts := []cmp.Option{
+ cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"),
+ cmpopts.EquateEmpty(),
+ }
+ require.Empty(t, cmp.Diff(want, resources, opts...))
+ })
+
+ t.Run("remove the watched file", func(t *testing.T) {
+ err := os.Remove(watchFilePath)
+ require.NoError(t, err)
+ require.Eventually(t, func() bool {
+ return pResources.GetResourcesByGatewayClass("eg") == nil
+ }, resourcesUpdateTimeout, resourcesUpdateTick)
+ })
+
+ t.Run("add a file in watched dir", func(t *testing.T) {
+ // Write a new file under watched directory.
+ newFilePath := filepath.Join(watchDirPath, "test.yaml")
+ writeResourcesFile(t, "testdata/resources.tmpl", newFilePath, newDefaultResourcesParam())
+
+ require.Eventually(t, func() bool {
+ return pResources.GetResourcesByGatewayClass("eg") != nil
+ }, resourcesUpdateTimeout, resourcesUpdateTick)
+
+ resources := pResources.GetResourcesByGatewayClass("eg")
+ want := &resource.Resources{}
+ mustUnmarshal(t, "testdata/resources.all.yaml", want)
+
+ opts := []cmp.Option{
+ cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"),
+ cmpopts.EquateEmpty(),
+ }
+ require.Empty(t, cmp.Diff(want, resources, opts...))
+ })
+
+ t.Run("remove a file in watched dir", func(t *testing.T) {
+ newFilePath := filepath.Join(watchDirPath, "test.yaml")
+ err := os.Remove(newFilePath)
+ require.NoError(t, err)
+ require.Eventually(t, func() bool {
+ return pResources.GetResourcesByGatewayClass("eg") == nil
+ }, resourcesUpdateTimeout, resourcesUpdateTick)
+ })
+
+ t.Cleanup(func() {
+ _ = os.RemoveAll(watchFileBase)
+ _ = os.RemoveAll(watchDirPath)
+ })
+}
+
+func writeResourcesFile(t *testing.T, tmpl, dst string, params *resourcesParam) {
+ dstFile, err := os.Create(dst)
+ require.NoError(t, err)
+
+ // Write parameters into target file.
+ tmplFile, err := template.ParseFiles(tmpl)
+ require.NoError(t, err)
+
+ err = tmplFile.Execute(dstFile, params)
+ require.NoError(t, err)
+ require.NoError(t, dstFile.Close())
+}
+
+func waitFileProviderReady(t *testing.T) {
+ require.Eventually(t, func() bool {
+ resp, err := http.Get("http://localhost:8081/readyz")
+ if err != nil {
+ t.Logf("failed to get from heathlz server")
+ return false
+ }
+
+ body, err := io.ReadAll(resp.Body)
+ defer resp.Body.Close()
+ if err != nil {
+ t.Logf("failed to get body from response")
+ return false
+ }
+
+ if string(body) != "ok" {
+ t.Logf("the file provider is not ready yet")
+ return false
+ }
+ return true
+ }, 3*resourcesUpdateTimeout, resourcesUpdateTick)
+}
+
+func mustUnmarshal(t *testing.T, path string, out interface{}) {
+ t.Helper()
+
+ content, err := os.ReadFile(path)
+ require.NoError(t, err)
+ require.NoError(t, yaml.UnmarshalStrict(content, out, yaml.DisallowUnknownFields))
+}
diff --git a/internal/provider/file/resources.go b/internal/provider/file/resources.go
new file mode 100644
index 00000000000..ac80863f740
--- /dev/null
+++ b/internal/provider/file/resources.go
@@ -0,0 +1,80 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package file
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
+)
+
+// loadFromFilesAndDirs loads resources from specific files and directories.
+func loadFromFilesAndDirs(files, dirs []string) ([]*resource.Resources, error) {
+ var rs []*resource.Resources
+
+ for _, file := range files {
+ r, err := loadFromFile(file)
+ if err != nil {
+ return nil, err
+ }
+ rs = append(rs, r)
+ }
+
+ for _, dir := range dirs {
+ r, err := loadFromDir(dir)
+ if err != nil {
+ return nil, err
+ }
+ rs = append(rs, r...)
+ }
+
+ return rs, nil
+}
+
+// loadFromFile loads resources from a specific file.
+func loadFromFile(path string) (*resource.Resources, error) {
+ if _, err := os.Stat(path); err != nil {
+ if os.IsNotExist(err) {
+ return nil, fmt.Errorf("file %s is not exist", path)
+ }
+ return nil, err
+ }
+
+ bytes, err := os.ReadFile(path)
+ if err != nil {
+ return nil, err
+ }
+
+ return resource.LoadResourcesFromYAMLBytes(bytes, false)
+}
+
+// loadFromDir loads resources from all the files under a specific directory excluding subdirectories.
+func loadFromDir(path string) ([]*resource.Resources, error) {
+ entries, err := os.ReadDir(path)
+ if err != nil {
+ return nil, err
+ }
+
+ var rs []*resource.Resources
+ for _, entry := range entries {
+ // Ignoring subdirectories and all hidden files and directories.
+ if entry.IsDir() || strings.HasPrefix(entry.Name(), ".") {
+ continue
+ }
+
+ r, err := loadFromFile(filepath.Join(path, entry.Name()))
+ if err != nil {
+ return nil, err
+ }
+
+ rs = append(rs, r)
+ }
+
+ return rs, nil
+}
diff --git a/internal/provider/file/store.go b/internal/provider/file/store.go
new file mode 100644
index 00000000000..448f1807cf0
--- /dev/null
+++ b/internal/provider/file/store.go
@@ -0,0 +1,73 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package file
+
+import (
+ "github.com/go-logr/logr"
+
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
+ "github.com/envoyproxy/gateway/internal/message"
+)
+
+type resourcesStore struct {
+ name string
+ resources *message.ProviderResources
+
+ logger logr.Logger
+}
+
+func newResourcesStore(name string, resources *message.ProviderResources, logger logr.Logger) *resourcesStore {
+ return &resourcesStore{
+ name: name,
+ resources: resources,
+ logger: logger,
+ }
+}
+
+// HandleEvent simply removes all the resources and triggers a resources reload from files
+// and directories despite of the event type.
+// TODO: Enhance this method by respecting the event type, and add support for multiple GatewayClass.
+func (r *resourcesStore) HandleEvent(files, dirs []string) {
+ r.logger.Info("reload all resources")
+
+ r.resources.GatewayAPIResources.Delete(r.name)
+ if err := r.LoadAndStore(files, dirs); err != nil {
+ r.logger.Error(err, "failed to load and store resources")
+ }
+}
+
+// LoadAndStore loads and stores all resources from files and directories.
+func (r *resourcesStore) LoadAndStore(files, dirs []string) error {
+ resources, err := loadFromFilesAndDirs(files, dirs)
+ if err != nil {
+ return err
+ }
+
+ // TODO(sh2): For now, we assume that one file only contains one GatewayClass and all its other
+ // related resources, like Gateway, HTTPRoute, etc. If we managed to extend Resources structure,
+ // we also need to process all the resources and its relationship, like what is done in
+ // Kubernetes provider. However, this will cause us to maintain two places of the same logic
+ // in each provider. The ideal case is two different providers share the same resources process logic.
+ //
+ // - This issue is tracked by https://github.com/envoyproxy/gateway/issues/3213
+
+ // We cannot make sure by the time the Write event was triggered, whether the GatewayClass exist,
+ // so here we just simply Store the first gatewayapi.Resources that has GatewayClass.
+ gwcResources := make(resource.ControllerResources, 0, 1)
+ for _, res := range resources {
+ if res.GatewayClass != nil {
+ gwcResources = append(gwcResources, res)
+ }
+ }
+ if len(gwcResources) == 0 {
+ return nil
+ }
+
+ r.resources.GatewayAPIResources.Store(r.name, &gwcResources)
+ r.logger.Info("loaded and stored resources successfully")
+
+ return nil
+}
diff --git a/internal/provider/file/testdata/resources.all.yaml b/internal/provider/file/testdata/resources.all.yaml
new file mode 100644
index 00000000000..079647dc6c0
--- /dev/null
+++ b/internal/provider/file/testdata/resources.all.yaml
@@ -0,0 +1,62 @@
+backends:
+- kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend
+ namespace: envoy-gateway-system
+ spec:
+ endpoints:
+ - ip:
+ address: 0.0.0.0
+ port: 3000
+ status: {}
+gatewayClass:
+ kind: GatewayClass
+ metadata:
+ creationTimestamp: null
+ name: eg
+ namespace: envoy-gateway-system
+ spec:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ status: {}
+gateways:
+- kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: eg
+ namespace: envoy-gateway-system
+ spec:
+ gatewayClassName: eg
+ listeners:
+ - name: http
+ port: 8888
+ protocol: HTTP
+ status: {}
+httpRoutes:
+- kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: backend
+ namespace: envoy-gateway-system
+ spec:
+ hostnames:
+ - www.example.com
+ parentRefs:
+ - name: eg
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend
+ matches:
+ - path:
+ type: PathPrefix
+ value: /
+ status:
+ parents: null
+namespaces:
+- metadata:
+ creationTimestamp: null
+ name: envoy-gateway-system
+ spec: {}
+ status: {}
diff --git a/internal/provider/file/testdata/resources.tmpl b/internal/provider/file/testdata/resources.tmpl
new file mode 100644
index 00000000000..f34bf1e0c3c
--- /dev/null
+++ b/internal/provider/file/testdata/resources.tmpl
@@ -0,0 +1,46 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+ name: {{.GatewayClassName}}
+spec:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+ name: {{.GatewayName}}
+spec:
+ gatewayClassName: {{.GatewayClassName}}
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: {{.GatewayListenerPort}}
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: {{.HTTPRouteName}}
+spec:
+ parentRefs:
+ - name: {{.GatewayName}}
+ hostnames:
+ - "www.example.com"
+ rules:
+ - backendRefs:
+ - group: "gateway.envoyproxy.io"
+ kind: Backend
+ name: {{.BackendName}}
+ matches:
+ - path:
+ type: PathPrefix
+ value: /
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: {{.BackendName}}
+spec:
+ endpoints:
+ - ip:
+ address: 0.0.0.0
+ port: 3000
diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go
index f7e88da222d..bcb6fa8772c 100644
--- a/internal/provider/kubernetes/controller.go
+++ b/internal/provider/kubernetes/controller.go
@@ -8,6 +8,7 @@ package kubernetes
import (
"context"
"fmt"
+ "time"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
@@ -20,6 +21,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/discovery"
+ "k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
@@ -37,13 +39,19 @@ import (
"github.com/envoyproxy/gateway/api/v1alpha1/validation"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/logging"
"github.com/envoyproxy/gateway/internal/message"
"github.com/envoyproxy/gateway/internal/utils"
"github.com/envoyproxy/gateway/internal/utils/slice"
+ "github.com/envoyproxy/gateway/internal/xds/bootstrap"
)
+var skipNameValidation = func() *bool {
+ return ptr.To(false)
+}
+
type gatewayAPIReconciler struct {
client client.Client
log logging.Logger
@@ -57,6 +65,21 @@ type gatewayAPIReconciler struct {
resources *message.ProviderResources
extGVKs []schema.GroupVersionKind
extServerPolicies []schema.GroupVersionKind
+
+ backendCRDExists bool
+ bTLSPolicyCRDExists bool
+ btpCRDExists bool
+ ctpCRDExists bool
+ eepCRDExists bool
+ epCRDExists bool
+ eppCRDExists bool
+ hrfCRDExists bool
+ grpcRouteCRDExists bool
+ serviceImportCRDExists bool
+ spCRDExists bool
+ tcpRouteCRDExists bool
+ tlsRouteCRDExists bool
+ udpRouteCRDExists bool
}
// newGatewayAPIController
@@ -79,13 +102,6 @@ func newGatewayAPIController(mgr manager.Manager, cfg *config.Server, su Updater
}
}
- byNamespaceSelector := cfg.EnvoyGateway.Provider != nil &&
- cfg.EnvoyGateway.Provider.Kubernetes != nil &&
- cfg.EnvoyGateway.Provider.Kubernetes.Watch != nil &&
- cfg.EnvoyGateway.Provider.Kubernetes.Watch.Type == egv1a1.KubernetesWatchModeTypeNamespaceSelector &&
- (cfg.EnvoyGateway.Provider.Kubernetes.Watch.NamespaceSelector.MatchLabels != nil ||
- len(cfg.EnvoyGateway.Provider.Kubernetes.Watch.NamespaceSelector.MatchExpressions) > 0)
-
r := &gatewayAPIReconciler{
client: mgr.GetClient(),
log: cfg.Logger,
@@ -100,60 +116,51 @@ func newGatewayAPIController(mgr manager.Manager, cfg *config.Server, su Updater
extServerPolicies: extServerPoliciesGVKs,
}
- if byNamespaceSelector {
+ if byNamespaceSelectorEnabled(cfg.EnvoyGateway) {
r.namespaceLabel = cfg.EnvoyGateway.Provider.Kubernetes.Watch.NamespaceSelector
}
- c, err := controller.New("gatewayapi", mgr, controller.Options{Reconciler: r})
+ // controller-runtime doesn't allow run controller with same name for more than once
+ // see https://github.com/kubernetes-sigs/controller-runtime/blob/2b941650bce159006c88bd3ca0d132c7bc40e947/pkg/controller/name.go#L29
+ name := fmt.Sprintf("gatewayapi-%d", time.Now().Unix())
+ c, err := controller.New(name, mgr, controller.Options{Reconciler: r, SkipNameValidation: skipNameValidation()})
if err != nil {
- return err
+ return fmt.Errorf("error creating controller: %w", err)
}
r.log.Info("created gatewayapi controller")
- // Subscribe to status updates
- r.subscribeAndUpdateStatus(ctx, cfg.EnvoyGateway.EnvoyGatewaySpec.ExtensionManager != nil)
-
// Watch resources
if err := r.watchResources(ctx, mgr, c); err != nil {
- return err
+ return fmt.Errorf("error watching resources: %w", err)
+ }
+
+ // When leader election is enabled, only subscribe to status updates upon acquiring leadership.
+ if cfg.EnvoyGateway.Provider.Type == egv1a1.ProviderTypeKubernetes &&
+ !ptr.Deref(cfg.EnvoyGateway.Provider.Kubernetes.LeaderElection.Disable, false) {
+ go func() {
+ cfg.Elected.Wait()
+ r.subscribeAndUpdateStatus(ctx, cfg.EnvoyGateway.EnvoyGatewaySpec.ExtensionManager != nil)
+ }()
+ } else {
+ r.subscribeAndUpdateStatus(ctx, cfg.EnvoyGateway.EnvoyGatewaySpec.ExtensionManager != nil)
}
return nil
}
-type resourceMappings struct {
- // Map for storing namespaces for Route, Service and Gateway objects.
- allAssociatedNamespaces sets.Set[string]
- // Map for storing EnvoyProxies' NamespacedNames attaching to Gateway or GatewayClass.
- allAssociatedEnvoyProxies sets.Set[string]
- // Map for storing TLSRoutes' NamespacedNames attaching to various Gateway objects.
- allAssociatedTLSRoutes sets.Set[string]
- // Map for storing HTTPRoutes' NamespacedNames attaching to various Gateway objects.
- allAssociatedHTTPRoutes sets.Set[string]
- // Map for storing GRPCRoutes' NamespacedNames attaching to various Gateway objects.
- allAssociatedGRPCRoutes sets.Set[string]
- // Map for storing TCPRoutes' NamespacedNames attaching to various Gateway objects.
- allAssociatedTCPRoutes sets.Set[string]
- // Map for storing UDPRoutes' NamespacedNames attaching to various Gateway objects.
- allAssociatedUDPRoutes sets.Set[string]
- // Map for storing backendRefs' NamespaceNames referred by various Route objects.
- allAssociatedBackendRefs sets.Set[gwapiv1.BackendObjectReference]
- // extensionRefFilters is a map of filters managed by an extension.
- // The key is the namespaced name, group and kind of the filter and the value is the
- // unstructured form of the resource.
- extensionRefFilters map[utils.NamespacedNameWithGroupKind]unstructured.Unstructured
-}
+func byNamespaceSelectorEnabled(eg *egv1a1.EnvoyGateway) bool {
+ if eg.Provider == nil ||
+ eg.Provider.Kubernetes == nil ||
+ eg.Provider.Kubernetes.Watch == nil {
+ return false
+ }
-func newResourceMapping() *resourceMappings {
- return &resourceMappings{
- allAssociatedNamespaces: sets.New[string](),
- allAssociatedEnvoyProxies: sets.New[string](),
- allAssociatedTLSRoutes: sets.New[string](),
- allAssociatedHTTPRoutes: sets.New[string](),
- allAssociatedGRPCRoutes: sets.New[string](),
- allAssociatedTCPRoutes: sets.New[string](),
- allAssociatedUDPRoutes: sets.New[string](),
- allAssociatedBackendRefs: sets.New[gwapiv1.BackendObjectReference](),
- extensionRefFilters: map[utils.NamespacedNameWithGroupKind]unstructured.Unstructured{},
+ watch := eg.Provider.Kubernetes.Watch
+ switch watch.Type {
+ case egv1a1.KubernetesWatchModeTypeNamespaceSelector:
+ // Make sure that the namespace selector has at least one label or expression is set.
+ return watch.NamespaceSelector.MatchLabels != nil || len(watch.NamespaceSelector.MatchExpressions) > 0
+ default:
+ return false
}
}
@@ -187,11 +194,10 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
// - Gateway API resources: Gateways, xRoutes ...
// - Envoy Gateway customized resources: EnvoyPatchPolicies, ClientTrafficPolicies, BackendTrafficPolicies ...
// - Referenced resources: Services, ServiceImports, EndpointSlices, Secrets, ConfigMaps ...
- gwcResources := make(gatewayapi.ControllerResources, 0, len(managedGCs))
+ gwcResources := make(resource.ControllerResources, 0, len(managedGCs))
for _, managedGC := range managedGCs {
// Initialize resource types.
- managedGC := managedGC
- gwcResource := gatewayapi.NewResources()
+ gwcResource := resource.NewResources()
gwcResource.GatewayClass = managedGC
gwcResources = append(gwcResources, gwcResource)
resourceMappings := newResourceMapping()
@@ -201,9 +207,12 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
if managedGC.Spec.ParametersRef != nil && managedGC.DeletionTimestamp == nil {
if err := r.processGatewayClassParamsRef(ctx, managedGC, resourceMappings, gwcResource); err != nil {
msg := fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err)
- if err := r.updateStatusForGatewayClass(ctx, managedGC, false, string(gwapiv1.GatewayClassReasonInvalidParameters), msg); err != nil {
- r.log.Error(err, "unable to update GatewayClass status")
- }
+ gc := status.SetGatewayClassAccepted(
+ managedGC.DeepCopy(),
+ false,
+ string(gwapiv1.GatewayClassReasonInvalidParameters),
+ msg)
+ r.resources.GatewayClassStatuses.Store(utils.NamespacedName(gc), &gc.Status)
r.log.Error(err, "failed to process parametersRef for gatewayclass", "name", managedGC.Name)
return reconcile.Result{}, err
}
@@ -214,42 +223,55 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
return reconcile.Result{}, err
}
- // Add all EnvoyPatchPolicies to the resourceTree
- if err = r.processEnvoyPatchPolicies(ctx, gwcResource); err != nil {
- return reconcile.Result{}, err
+ if r.eppCRDExists {
+ // Add all EnvoyPatchPolicies to the resourceTree
+ if err = r.processEnvoyPatchPolicies(ctx, gwcResource, resourceMappings); err != nil {
+ return reconcile.Result{}, err
+ }
}
-
- // Add all ClientTrafficPolicies and their referenced resources to the resourceTree
- if err = r.processClientTrafficPolicies(ctx, gwcResource, resourceMappings); err != nil {
- return reconcile.Result{}, err
+ if r.ctpCRDExists {
+ // Add all ClientTrafficPolicies and their referenced resources to the resourceTree
+ if err = r.processClientTrafficPolicies(ctx, gwcResource, resourceMappings); err != nil {
+ return reconcile.Result{}, err
+ }
}
- // Add all BackendTrafficPolicies to the resourceTree
- if err = r.processBackendTrafficPolicies(ctx, gwcResource); err != nil {
- return reconcile.Result{}, err
+ if r.btpCRDExists {
+ // Add all BackendTrafficPolicies to the resourceTree
+ if err = r.processBackendTrafficPolicies(ctx, gwcResource, resourceMappings); err != nil {
+ return reconcile.Result{}, err
+ }
}
- // Add all SecurityPolicies and their referenced resources to the resourceTree
- if err = r.processSecurityPolicies(ctx, gwcResource, resourceMappings); err != nil {
- return reconcile.Result{}, err
+ if r.spCRDExists {
+ // Add all SecurityPolicies and their referenced resources to the resourceTree
+ if err = r.processSecurityPolicies(ctx, gwcResource, resourceMappings); err != nil {
+ return reconcile.Result{}, err
+ }
}
- // Add all BackendTLSPolies to the resourceTree
- if err = r.processBackendTLSPolicies(ctx, gwcResource, resourceMappings); err != nil {
- return reconcile.Result{}, err
+ if r.bTLSPolicyCRDExists {
+ // Add all BackendTLSPolies to the resourceTree
+ if err = r.processBackendTLSPolicies(ctx, gwcResource, resourceMappings); err != nil {
+ return reconcile.Result{}, err
+ }
}
- // Add all EnvoyExtensionPolicies and their referenced resources to the resourceTree
- if err = r.processEnvoyExtensionPolicies(ctx, gwcResource, resourceMappings); err != nil {
- return reconcile.Result{}, err
+ if r.eepCRDExists {
+ // Add all EnvoyExtensionPolicies and their referenced resources to the resourceTree
+ if err = r.processEnvoyExtensionPolicies(ctx, gwcResource, resourceMappings); err != nil {
+ return reconcile.Result{}, err
+ }
}
if err = r.processExtensionServerPolicies(ctx, gwcResource); err != nil {
return reconcile.Result{}, err
}
- if err = r.processBackends(ctx, gwcResource); err != nil {
- return reconcile.Result{}, err
+ if r.backendCRDExists {
+ if err = r.processBackends(ctx, gwcResource); err != nil {
+ return reconcile.Result{}, err
+ }
}
// Add the referenced services, ServiceImports, and EndpointSlices in
@@ -282,11 +304,12 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
// process envoy gateway secret refs
r.processEnvoyProxySecretRef(ctx, gwcResource)
-
- if err := r.updateStatusForGatewayClass(ctx, managedGC, true, string(gwapiv1.GatewayClassReasonAccepted), status.MsgValidGatewayClass); err != nil {
- r.log.Error(err, "unable to update GatewayClass status")
- return reconcile.Result{}, err
- }
+ gc := status.SetGatewayClassAccepted(
+ managedGC.DeepCopy(),
+ true,
+ string(gwapiv1.GatewayClassReasonAccepted),
+ status.MsgValidGatewayClass)
+ r.resources.GatewayClassStatuses.Store(utils.NamespacedName(gc), &gc.Status)
if len(gwcResource.Gateways) == 0 {
r.log.Info("No gateways found for accepted gatewayclass")
@@ -317,7 +340,7 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
return reconcile.Result{}, nil
}
-func (r *gatewayAPIReconciler) processEnvoyProxySecretRef(ctx context.Context, gwcResource *gatewayapi.Resources) {
+func (r *gatewayAPIReconciler) processEnvoyProxySecretRef(ctx context.Context, gwcResource *resource.Resources) {
if gwcResource.EnvoyProxyForGatewayClass == nil || gwcResource.EnvoyProxyForGatewayClass.Spec.BackendTLS == nil || gwcResource.EnvoyProxyForGatewayClass.Spec.BackendTLS.ClientCertificateRef == nil {
return
}
@@ -327,9 +350,9 @@ func (r *gatewayAPIReconciler) processEnvoyProxySecretRef(ctx context.Context, g
ctx,
newResourceMapping(),
gwcResource,
- gatewayapi.KindGateway,
+ resource.KindGateway,
gwcResource.EnvoyProxyForGatewayClass.Namespace,
- gatewayapi.KindEnvoyProxy,
+ resource.KindEnvoyProxy,
*certRef); err != nil {
r.log.Error(err,
"failed to process TLS SecretRef for EnvoyProxy",
@@ -348,13 +371,12 @@ func (r *gatewayAPIReconciler) managedGatewayClasses(ctx context.Context) ([]*gw
var cc controlledClasses
for _, gwClass := range gatewayClasses.Items {
- gwClass := gwClass
if gwClass.Spec.ControllerName == r.classController {
// The gatewayclass was marked for deletion and the finalizer removed,
// so clean-up dependents.
if !gwClass.DeletionTimestamp.IsZero() &&
!slice.ContainsString(gwClass.Finalizers, gatewayClassFinalizer) {
- r.log.Info("gatewayclass marked for deletion")
+ r.log.Info("gatewayclass marked for deletion", "name", gwClass.Name)
cc.removeMatch(&gwClass)
continue
}
@@ -371,15 +393,15 @@ func (r *gatewayAPIReconciler) managedGatewayClasses(ctx context.Context) ([]*gw
// - ServiceImports
// - EndpointSlices
// - Backends
-func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResource *gatewayapi.Resources, resourceMappings *resourceMappings) {
+func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResource *resource.Resources, resourceMappings *resourceMappings) {
for backendRef := range resourceMappings.allAssociatedBackendRefs {
- backendRefKind := gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService)
+ backendRefKind := gatewayapi.KindDerefOr(backendRef.Kind, resource.KindService)
r.log.Info("processing Backend", "kind", backendRefKind, "namespace", string(*backendRef.Namespace),
"name", string(backendRef.Name))
var endpointSliceLabelKey string
switch backendRefKind {
- case gatewayapi.KindService:
+ case resource.KindService:
service := new(corev1.Service)
err := r.client.Get(ctx, types.NamespacedName{Namespace: string(*backendRef.Namespace), Name: string(backendRef.Name)}, service)
if err != nil {
@@ -393,7 +415,7 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour
}
endpointSliceLabelKey = discoveryv1.LabelServiceName
- case gatewayapi.KindServiceImport:
+ case resource.KindServiceImport:
serviceImport := new(mcsapiv1a1.ServiceImport)
err := r.client.Get(ctx, types.NamespacedName{Namespace: string(*backendRef.Namespace), Name: string(backendRef.Name)}, serviceImport)
if err != nil {
@@ -401,9 +423,13 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour
"name", string(backendRef.Name))
} else {
resourceMappings.allAssociatedNamespaces.Insert(serviceImport.Namespace)
- gwcResource.ServiceImports = append(gwcResource.ServiceImports, serviceImport)
- r.log.Info("added ServiceImport to resource tree", "namespace", string(*backendRef.Namespace),
- "name", string(backendRef.Name))
+ key := utils.NamespacedName(serviceImport).String()
+ if !resourceMappings.allAssociatedServiceImports.Has(key) {
+ resourceMappings.allAssociatedServiceImports.Insert(key)
+ gwcResource.ServiceImports = append(gwcResource.ServiceImports, serviceImport)
+ r.log.Info("added ServiceImport to resource tree", "namespace", string(*backendRef.Namespace),
+ "name", string(backendRef.Name))
+ }
}
endpointSliceLabelKey = mcsapiv1a1.LabelServiceName
@@ -414,10 +440,14 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour
r.log.Error(err, "failed to get Backend", "namespace", string(*backendRef.Namespace),
"name", string(backendRef.Name))
} else {
- resourceMappings.allAssociatedNamespaces[backend.Namespace] = struct{}{}
- gwcResource.Backends = append(gwcResource.Backends, backend)
- r.log.Info("added Backend to resource tree", "namespace", string(*backendRef.Namespace),
- "name", string(backendRef.Name))
+ resourceMappings.allAssociatedNamespaces.Insert(backend.Namespace)
+ key := utils.NamespacedName(backend).String()
+ if !resourceMappings.allAssociatedBackends.Has(key) {
+ resourceMappings.allAssociatedBackends.Insert(key)
+ gwcResource.Backends = append(gwcResource.Backends, backend)
+ r.log.Info("added Backend to resource tree", "namespace", string(*backendRef.Namespace),
+ "name", string(backendRef.Name))
+ }
}
}
@@ -428,17 +458,21 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour
client.MatchingLabels(map[string]string{
endpointSliceLabelKey: string(backendRef.Name),
}),
- client.InNamespace(string(*backendRef.Namespace)),
+ client.InNamespace(*backendRef.Namespace),
}
if err := r.client.List(ctx, endpointSliceList, opts...); err != nil {
r.log.Error(err, "failed to get EndpointSlices", "namespace", string(*backendRef.Namespace),
backendRefKind, string(backendRef.Name))
} else {
for _, endpointSlice := range endpointSliceList.Items {
- endpointSlice := endpointSlice
- r.log.Info("added EndpointSlice to resource tree", "namespace", endpointSlice.Namespace,
- "name", endpointSlice.Name)
- gwcResource.EndpointSlices = append(gwcResource.EndpointSlices, &endpointSlice)
+ key := utils.NamespacedName(&endpointSlice).String()
+ if !resourceMappings.allAssociatedEndpointSlices.Has(key) {
+ resourceMappings.allAssociatedEndpointSlices.Insert(key)
+ r.log.Info("added EndpointSlice to resource tree",
+ "namespace", endpointSlice.Namespace,
+ "name", endpointSlice.Name)
+ gwcResource.EndpointSlices = append(gwcResource.EndpointSlices, &endpointSlice)
+ }
}
}
}
@@ -450,7 +484,7 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour
// - Secrets for OIDC and BasicAuth
// - BackendRefs for ExAuth
func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs(
- ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings,
+ ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings,
) {
// we don't return errors from this method, because we want to continue reconciling
// the rest of the SecurityPolicies despite that one reference is invalid. This
@@ -468,7 +502,7 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs(
ctx,
resourceMap,
resourceTree,
- gatewayapi.KindSecurityPolicy,
+ resource.KindSecurityPolicy,
policy.Namespace,
policy.Name,
oidc.ClientSecret); err != nil {
@@ -485,7 +519,7 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs(
ctx,
resourceMap,
resourceTree,
- gatewayapi.KindSecurityPolicy,
+ resource.KindSecurityPolicy,
policy.Namespace,
policy.Name,
basicAuth.Users); err != nil {
@@ -525,12 +559,12 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs(
if backendNamespace != policy.Namespace {
from := ObjectKindNamespacedName{
- kind: gatewayapi.KindSecurityPolicy,
+ kind: resource.KindSecurityPolicy,
namespace: policy.Namespace,
name: policy.Name,
}
to := ObjectKindNamespacedName{
- kind: gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService),
+ kind: gatewayapi.KindDerefOr(backendRef.Kind, resource.KindService),
namespace: backendNamespace,
name: string(backendRef.Name),
}
@@ -542,9 +576,12 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs(
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
- resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
- r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
- "name", refGrant.Name)
+ if !resourceMap.allAssociatedReferenceGrants.Has(utils.NamespacedName(refGrant).String()) {
+ resourceMap.allAssociatedReferenceGrants.Insert(utils.NamespacedName(refGrant).String())
+ resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
+ r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
+ "name", refGrant.Name)
+ }
}
}
}
@@ -554,7 +591,7 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs(
// processOIDCHMACSecret adds the OIDC HMAC Secret to the resourceTree.
// The OIDC HMAC Secret is created by the CertGen job and is used by SecurityPolicy
// to configure OAuth2 filters.
-func (r *gatewayAPIReconciler) processOIDCHMACSecret(ctx context.Context, resourceTree *gatewayapi.Resources) {
+func (r *gatewayAPIReconciler) processOIDCHMACSecret(ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings) {
var (
secret corev1.Secret
err error
@@ -575,8 +612,12 @@ func (r *gatewayAPIReconciler) processOIDCHMACSecret(ctx context.Context, resour
return
}
- resourceTree.Secrets = append(resourceTree.Secrets, &secret)
- r.log.Info("processing OIDC HMAC Secret", "namespace", r.namespace, "name", oidcHMACSecretName)
+ key := utils.NamespacedName(&secret).String()
+ if !resourceMap.allAssociatedSecrets.Has(key) {
+ resourceMap.allAssociatedSecrets.Insert(key)
+ resourceTree.Secrets = append(resourceTree.Secrets, &secret)
+ r.log.Info("processing OIDC HMAC Secret", "namespace", r.namespace, "name", oidcHMACSecretName)
+ }
}
// processSecretRef adds the referenced Secret to the resourceTree if it's valid.
@@ -585,11 +626,11 @@ func (r *gatewayAPIReconciler) processOIDCHMACSecret(ctx context.Context, resour
func (r *gatewayAPIReconciler) processSecretRef(
ctx context.Context,
resourceMap *resourceMappings,
- resourceTree *gatewayapi.Resources,
+ resourceTree *resource.Resources,
ownerKind string,
ownerNS string,
ownerName string,
- secretRef gwapiv1b1.SecretObjectReference,
+ secretRef gwapiv1.SecretObjectReference,
) error {
secret := new(corev1.Secret)
secretNS := gatewayapi.NamespaceDerefOr(secretRef.Namespace, ownerNS)
@@ -597,7 +638,7 @@ func (r *gatewayAPIReconciler) processSecretRef(
types.NamespacedName{Namespace: secretNS, Name: string(secretRef.Name)},
secret,
)
- if err != nil && !kerrors.IsNotFound(err) {
+ if err != nil && kerrors.IsNotFound(err) {
return fmt.Errorf("unable to find the Secret: %s/%s", secretNS, string(secretRef.Name))
}
@@ -608,7 +649,7 @@ func (r *gatewayAPIReconciler) processSecretRef(
name: ownerName,
}
to := ObjectKindNamespacedName{
- kind: gatewayapi.KindSecret,
+ kind: resource.KindSecret,
namespace: secretNS,
name: secret.Name,
}
@@ -622,33 +663,40 @@ func (r *gatewayAPIReconciler) processSecretRef(
from.kind, from.namespace, to.kind, to.namespace)
default:
// RefGrant found
- resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
- r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
- "name", refGrant.Name)
+ if !resourceMap.allAssociatedReferenceGrants.Has(utils.NamespacedName(refGrant).String()) {
+ resourceMap.allAssociatedReferenceGrants.Insert(utils.NamespacedName(refGrant).String())
+ resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
+ r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
+ "name", refGrant.Name)
+ }
}
}
- resourceMap.allAssociatedNamespaces.Insert(secretNS) // TODO Zhaohuabing do we need this line?
- resourceTree.Secrets = append(resourceTree.Secrets, secret)
- r.log.Info("processing Secret", "namespace", secretNS, "name", string(secretRef.Name))
+ resourceMap.allAssociatedNamespaces.Insert(secretNS)
+ key := utils.NamespacedName(secret).String()
+ if !resourceMap.allAssociatedSecrets.Has(key) {
+ resourceMap.allAssociatedSecrets.Insert(key)
+ resourceTree.Secrets = append(resourceTree.Secrets, secret)
+ r.log.Info("processing Secret", "namespace", secretNS, "name", string(secretRef.Name))
+ }
return nil
}
// processCtpConfigMapRefs adds the referenced ConfigMaps in ClientTrafficPolicies
// to the resourceTree
func (r *gatewayAPIReconciler) processCtpConfigMapRefs(
- ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings,
+ ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings,
) {
for _, policy := range resourceTree.ClientTrafficPolicies {
tls := policy.Spec.TLS
if tls != nil && tls.ClientValidation != nil {
for _, caCertRef := range tls.ClientValidation.CACertificateRefs {
- if caCertRef.Kind != nil && string(*caCertRef.Kind) == gatewayapi.KindConfigMap {
+ if caCertRef.Kind != nil && string(*caCertRef.Kind) == resource.KindConfigMap {
if err := r.processConfigMapRef(
ctx,
resourceMap,
resourceTree,
- gatewayapi.KindClientTrafficPolicy,
+ resource.KindClientTrafficPolicy,
policy.Namespace,
policy.Name,
caCertRef); err != nil {
@@ -662,12 +710,12 @@ func (r *gatewayAPIReconciler) processCtpConfigMapRefs(
"failed to process CACertificateRef for ClientTrafficPolicy",
"policy", policy, "caCertificateRef", caCertRef.Name)
}
- } else if caCertRef.Kind == nil || string(*caCertRef.Kind) == gatewayapi.KindSecret {
+ } else if caCertRef.Kind == nil || string(*caCertRef.Kind) == resource.KindSecret {
if err := r.processSecretRef(
ctx,
resourceMap,
resourceTree,
- gatewayapi.KindClientTrafficPolicy,
+ resource.KindClientTrafficPolicy,
policy.Namespace,
policy.Name,
caCertRef); err != nil {
@@ -687,11 +735,11 @@ func (r *gatewayAPIReconciler) processCtpConfigMapRefs(
func (r *gatewayAPIReconciler) processConfigMapRef(
ctx context.Context,
resourceMap *resourceMappings,
- resourceTree *gatewayapi.Resources,
+ resourceTree *resource.Resources,
ownerKind string,
ownerNS string,
ownerName string,
- configMapRef gwapiv1b1.SecretObjectReference,
+ configMapRef gwapiv1.SecretObjectReference,
) error {
configMap := new(corev1.ConfigMap)
configMapNS := gatewayapi.NamespaceDerefOr(configMapRef.Namespace, ownerNS)
@@ -699,7 +747,7 @@ func (r *gatewayAPIReconciler) processConfigMapRef(
types.NamespacedName{Namespace: configMapNS, Name: string(configMapRef.Name)},
configMap,
)
- if err != nil && !kerrors.IsNotFound(err) {
+ if err != nil && kerrors.IsNotFound(err) {
return fmt.Errorf("unable to find the ConfigMap: %s/%s", configMapNS, string(configMapRef.Name))
}
@@ -710,7 +758,7 @@ func (r *gatewayAPIReconciler) processConfigMapRef(
name: ownerName,
}
to := ObjectKindNamespacedName{
- kind: gatewayapi.KindConfigMap,
+ kind: resource.KindConfigMap,
namespace: configMapNS,
name: configMap.Name,
}
@@ -724,17 +772,59 @@ func (r *gatewayAPIReconciler) processConfigMapRef(
from.kind, from.namespace, to.kind, to.namespace)
default:
// RefGrant found
- resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
- r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
- "name", refGrant.Name)
+ if !resourceMap.allAssociatedReferenceGrants.Has(utils.NamespacedName(refGrant).String()) {
+ resourceMap.allAssociatedReferenceGrants.Insert(utils.NamespacedName(refGrant).String())
+ resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
+ r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
+ "name", refGrant.Name)
+ }
}
}
- resourceMap.allAssociatedNamespaces.Insert(configMapNS) // TODO Zhaohuabing do we need this line?
- resourceTree.ConfigMaps = append(resourceTree.ConfigMaps, configMap)
- r.log.Info("processing ConfigMap", "namespace", configMapNS, "name", string(configMapRef.Name))
+ resourceMap.allAssociatedNamespaces.Insert(configMapNS)
+ if !resourceMap.allAssociatedConfigMaps.Has(utils.NamespacedName(configMap).String()) {
+ resourceMap.allAssociatedConfigMaps.Insert(utils.NamespacedName(configMap).String())
+ resourceTree.ConfigMaps = append(resourceTree.ConfigMaps, configMap)
+ r.log.Info("processing ConfigMap", "namespace", configMapNS, "name", string(configMapRef.Name))
+ }
return nil
}
+// processBtpConfigMapRefs adds the referenced ConfigMaps in BackendTrafficPolicies
+// to the resourceTree
+func (r *gatewayAPIReconciler) processBtpConfigMapRefs(
+ ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings,
+) {
+ for _, policy := range resourceTree.BackendTrafficPolicies {
+ for _, ro := range policy.Spec.ResponseOverride {
+ if ro.Response.Body.ValueRef != nil && string(ro.Response.Body.ValueRef.Kind) == resource.KindConfigMap {
+ configMap := new(corev1.ConfigMap)
+ err := r.client.Get(ctx,
+ types.NamespacedName{Namespace: policy.Namespace, Name: string(ro.Response.Body.ValueRef.Name)},
+ configMap,
+ )
+ // we don't return an error here, because we want to continue
+ // reconciling the rest of the BackendTrafficPolicies despite that this
+ // reference is invalid.
+ // This BackendTrafficPolicies will be marked as invalid in its status
+ // when translating to IR because the referenced configmap can't be
+ // found.
+ if err != nil {
+ r.log.Error(err,
+ "failed to process ResponseOverride ValueRef for BackendTrafficPolicy",
+ "policy", policy, "ValueRef", ro.Response.Body.ValueRef.Name)
+ }
+
+ resourceMap.allAssociatedNamespaces.Insert(policy.Namespace)
+ if !resourceMap.allAssociatedConfigMaps.Has(utils.NamespacedName(configMap).String()) {
+ resourceMap.allAssociatedConfigMaps.Insert(utils.NamespacedName(configMap).String())
+ resourceTree.ConfigMaps = append(resourceTree.ConfigMaps, configMap)
+ r.log.Info("processing ConfigMap", "namespace", policy.Namespace, "name", string(ro.Response.Body.ValueRef.Name))
+ }
+ }
+ }
+ }
+}
+
func (r *gatewayAPIReconciler) getNamespace(ctx context.Context, name string) (*corev1.Namespace, error) {
nsKey := types.NamespacedName{Name: name}
ns := new(corev1.Namespace)
@@ -756,7 +846,6 @@ func (r *gatewayAPIReconciler) findReferenceGrant(ctx context.Context, from, to
if r.namespaceLabel != nil {
var rgs []gwapiv1b1.ReferenceGrant
for _, refGrant := range refGrants {
- refGrant := refGrant
if ok, err := r.checkObjectNamespaceLabels(&refGrant); err != nil {
r.log.Error(err, "failed to check namespace labels for ReferenceGrant %s in namespace %s: %w", refGrant.GetName(), refGrant.GetNamespace())
continue
@@ -769,20 +858,42 @@ func (r *gatewayAPIReconciler) findReferenceGrant(ctx context.Context, from, to
}
for _, refGrant := range refGrants {
- if refGrant.Namespace == to.namespace {
- for _, src := range refGrant.Spec.From {
- if src.Kind == gwapiv1a2.Kind(from.kind) && string(src.Namespace) == from.namespace {
- return &refGrant, nil
- }
+ if refGrant.Namespace != to.namespace {
+ continue
+ }
+
+ var fromAllowed bool
+ for _, refGrantFrom := range refGrant.Spec.From {
+ if string(refGrantFrom.Kind) == from.kind && string(refGrantFrom.Namespace) == from.namespace {
+ fromAllowed = true
+ break
+ }
+ }
+
+ if !fromAllowed {
+ continue
+ }
+
+ var toAllowed bool
+ for _, refGrantTo := range refGrant.Spec.To {
+ if string(refGrantTo.Kind) == to.kind && (refGrantTo.Name == nil || *refGrantTo.Name == "" || string(*refGrantTo.Name) == to.name) {
+ toAllowed = true
+ break
}
}
+
+ if !toAllowed {
+ continue
+ }
+
+ return &refGrant, nil
}
// No ReferenceGrant found.
return nil, nil
}
-func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *gwapiv1.GatewayClass, resourceMap *resourceMappings, resourceTree *gatewayapi.Resources) error {
+func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *gwapiv1.GatewayClass, resourceMap *resourceMappings, resourceTree *resource.Resources) error {
// Find gateways for the managedGC
// Find the Gateways that reference this Class.
gatewayList := &gwapiv1.GatewayList{}
@@ -794,7 +905,7 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g
}
for _, gtw := range gatewayList.Items {
- gtw := gtw
+ gtw := gtw //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(>w); err != nil {
r.log.Error(err, "failed to check namespace labels for gateway %s in namespace %s: %w", gtw.GetName(), gtw.GetNamespace())
@@ -811,17 +922,15 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g
}
for _, listener := range gtw.Spec.Listeners {
- listener := listener
// Get Secret for gateway if it exists.
if terminatesTLS(&listener) {
for _, certRef := range listener.TLS.CertificateRefs {
- certRef := certRef
if refsSecret(&certRef) {
if err := r.processSecretRef(
ctx,
resourceMap,
resourceTree,
- gatewayapi.KindGateway,
+ resource.KindGateway,
gtw.Namespace,
gtw.Name,
certRef); err != nil {
@@ -834,62 +943,76 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g
}
}
+ gtwNamespacedName := utils.NamespacedName(>w).String()
// Route Processing
- // Get TLSRoute objects and check if it exists.
- if err := r.processTLSRoutes(ctx, utils.NamespacedName(>w).String(), resourceMap, resourceTree); err != nil {
- return err
+
+ if r.tlsRouteCRDExists {
+ // Get TLSRoute objects and check if it exists.
+ if err := r.processTLSRoutes(ctx, gtwNamespacedName, resourceMap, resourceTree); err != nil {
+ return err
+ }
}
// Get HTTPRoute objects and check if it exists.
- if err := r.processHTTPRoutes(ctx, utils.NamespacedName(>w).String(), resourceMap, resourceTree); err != nil {
+ if err := r.processHTTPRoutes(ctx, gtwNamespacedName, resourceMap, resourceTree); err != nil {
return err
}
- // Get GRPCRoute objects and check if it exists.
- if err := r.processGRPCRoutes(ctx, utils.NamespacedName(>w).String(), resourceMap, resourceTree); err != nil {
- return err
+ if r.grpcRouteCRDExists {
+ // Get GRPCRoute objects and check if it exists.
+ if err := r.processGRPCRoutes(ctx, gtwNamespacedName, resourceMap, resourceTree); err != nil {
+ return err
+ }
}
- // Get TCPRoute objects and check if it exists.
- if err := r.processTCPRoutes(ctx, utils.NamespacedName(>w).String(), resourceMap, resourceTree); err != nil {
- return err
+ if r.tcpRouteCRDExists {
+ // Get TCPRoute objects and check if it exists.
+ if err := r.processTCPRoutes(ctx, gtwNamespacedName, resourceMap, resourceTree); err != nil {
+ return err
+ }
}
- // Get UDPRoute objects and check if it exists.
- if err := r.processUDPRoutes(ctx, utils.NamespacedName(>w).String(), resourceMap, resourceTree); err != nil {
- return err
+ if r.udpRouteCRDExists {
+ // Get UDPRoute objects and check if it exists.
+ if err := r.processUDPRoutes(ctx, gtwNamespacedName, resourceMap, resourceTree); err != nil {
+ return err
+ }
}
-
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
gtw.Status = gwapiv1.GatewayStatus{}
- resourceTree.Gateways = append(resourceTree.Gateways, >w)
+ if !resourceMap.allAssociatedGateways.Has(gtwNamespacedName) {
+ resourceMap.allAssociatedGateways.Insert(gtwNamespacedName)
+ resourceTree.Gateways = append(resourceTree.Gateways, >w)
+ }
}
return nil
}
// processEnvoyPatchPolicies adds EnvoyPatchPolicies to the resourceTree
-func (r *gatewayAPIReconciler) processEnvoyPatchPolicies(ctx context.Context, resourceTree *gatewayapi.Resources) error {
+func (r *gatewayAPIReconciler) processEnvoyPatchPolicies(ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings) error {
envoyPatchPolicies := egv1a1.EnvoyPatchPolicyList{}
if err := r.client.List(ctx, &envoyPatchPolicies); err != nil {
return fmt.Errorf("error listing EnvoyPatchPolicies: %w", err)
}
for _, policy := range envoyPatchPolicies.Items {
- policy := policy
+ envoyPatchPolicy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
- policy.Status = gwapiv1a2.PolicyStatus{}
-
- resourceTree.EnvoyPatchPolicies = append(resourceTree.EnvoyPatchPolicies, &policy)
+ envoyPatchPolicy.Status = gwapiv1a2.PolicyStatus{}
+ if !resourceMap.allAssociatedEnvoyPatchPolicies.Has(utils.NamespacedName(&envoyPatchPolicy).String()) {
+ resourceMap.allAssociatedEnvoyPatchPolicies.Insert(utils.NamespacedName(&envoyPatchPolicy).String())
+ resourceTree.EnvoyPatchPolicies = append(resourceTree.EnvoyPatchPolicies, &envoyPatchPolicy)
+ }
}
return nil
}
// processClientTrafficPolicies adds ClientTrafficPolicies to the resourceTree
func (r *gatewayAPIReconciler) processClientTrafficPolicies(
- ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings,
+ ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings,
) error {
clientTrafficPolicies := egv1a1.ClientTrafficPolicyList{}
if err := r.client.List(ctx, &clientTrafficPolicies); err != nil {
@@ -897,11 +1020,14 @@ func (r *gatewayAPIReconciler) processClientTrafficPolicies(
}
for _, policy := range clientTrafficPolicies.Items {
- policy := policy
+ clientTrafficPolicy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
- policy.Status = gwapiv1a2.PolicyStatus{}
- resourceTree.ClientTrafficPolicies = append(resourceTree.ClientTrafficPolicies, &policy)
+ clientTrafficPolicy.Status = gwapiv1a2.PolicyStatus{}
+ if !resourceMap.allAssociatedClientTrafficPolicies.Has(utils.NamespacedName(&clientTrafficPolicy).String()) {
+ resourceMap.allAssociatedClientTrafficPolicies.Insert(utils.NamespacedName(&clientTrafficPolicy).String())
+ resourceTree.ClientTrafficPolicies = append(resourceTree.ClientTrafficPolicies, &clientTrafficPolicy)
+ }
}
r.processCtpConfigMapRefs(ctx, resourceTree, resourceMap)
@@ -910,25 +1036,30 @@ func (r *gatewayAPIReconciler) processClientTrafficPolicies(
}
// processBackendTrafficPolicies adds BackendTrafficPolicies to the resourceTree
-func (r *gatewayAPIReconciler) processBackendTrafficPolicies(ctx context.Context, resourceTree *gatewayapi.Resources) error {
+func (r *gatewayAPIReconciler) processBackendTrafficPolicies(ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings,
+) error {
backendTrafficPolicies := egv1a1.BackendTrafficPolicyList{}
if err := r.client.List(ctx, &backendTrafficPolicies); err != nil {
return fmt.Errorf("error listing BackendTrafficPolicies: %w", err)
}
for _, policy := range backendTrafficPolicies.Items {
- policy := policy
+ backendTrafficPolicy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
- policy.Status = gwapiv1a2.PolicyStatus{}
- resourceTree.BackendTrafficPolicies = append(resourceTree.BackendTrafficPolicies, &policy)
+ backendTrafficPolicy.Status = gwapiv1a2.PolicyStatus{}
+ if !resourceMap.allAssociatedBackendTrafficPolicies.Has(utils.NamespacedName(&backendTrafficPolicy).String()) {
+ resourceMap.allAssociatedBackendTrafficPolicies.Insert(utils.NamespacedName(&backendTrafficPolicy).String())
+ resourceTree.BackendTrafficPolicies = append(resourceTree.BackendTrafficPolicies, &backendTrafficPolicy)
+ }
}
+ r.processBtpConfigMapRefs(ctx, resourceTree, resourceMap)
return nil
}
// processSecurityPolicies adds SecurityPolicies and their referenced resources to the resourceTree
func (r *gatewayAPIReconciler) processSecurityPolicies(
- ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings,
+ ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings,
) error {
securityPolicies := egv1a1.SecurityPolicyList{}
if err := r.client.List(ctx, &securityPolicies); err != nil {
@@ -936,24 +1067,27 @@ func (r *gatewayAPIReconciler) processSecurityPolicies(
}
for _, policy := range securityPolicies.Items {
- policy := policy
+ securityPolicy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
- policy.Status = gwapiv1a2.PolicyStatus{}
- resourceTree.SecurityPolicies = append(resourceTree.SecurityPolicies, &policy)
+ securityPolicy.Status = gwapiv1a2.PolicyStatus{}
+ if !resourceMap.allAssociatedSecurityPolicies.Has(utils.NamespacedName(&securityPolicy).String()) {
+ resourceMap.allAssociatedSecurityPolicies.Insert(utils.NamespacedName(&securityPolicy).String())
+ resourceTree.SecurityPolicies = append(resourceTree.SecurityPolicies, &securityPolicy)
+ }
}
// Add the referenced Resources in SecurityPolicies to the resourceTree
r.processSecurityPolicyObjectRefs(ctx, resourceTree, resourceMap)
// Add the OIDC HMAC Secret to the resourceTree
- r.processOIDCHMACSecret(ctx, resourceTree)
+ r.processOIDCHMACSecret(ctx, resourceTree, resourceMap)
return nil
}
// processBackendTLSPolicies adds BackendTLSPolicies and their referenced resources to the resourceTree
func (r *gatewayAPIReconciler) processBackendTLSPolicies(
- ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings,
+ ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings,
) error {
backendTLSPolicies := gwapiv1a3.BackendTLSPolicyList{}
if err := r.client.List(ctx, &backendTLSPolicies); err != nil {
@@ -961,11 +1095,14 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicies(
}
for _, policy := range backendTLSPolicies.Items {
- policy := policy
+ backendTLSPolicy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
- policy.Status = gwapiv1a2.PolicyStatus{}
- resourceTree.BackendTLSPolicies = append(resourceTree.BackendTLSPolicies, &policy)
+ backendTLSPolicy.Status = gwapiv1a2.PolicyStatus{}
+ if !resourceMap.allAssociatedBackendTLSPolicies.Has(utils.NamespacedName(&backendTLSPolicy).String()) {
+ resourceMap.allAssociatedBackendTLSPolicies.Insert(utils.NamespacedName(&backendTLSPolicy).String())
+ resourceTree.BackendTLSPolicies = append(resourceTree.BackendTLSPolicies, &backendTLSPolicy)
+ }
}
// Add the referenced Secrets and ConfigMaps in BackendTLSPolicies to the resourceTree.
@@ -974,18 +1111,17 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicies(
}
// processBackends adds Backends to the resourceTree
-func (r *gatewayAPIReconciler) processBackends(ctx context.Context, resourceTree *gatewayapi.Resources) error {
+func (r *gatewayAPIReconciler) processBackends(ctx context.Context, resourceTree *resource.Resources) error {
backends := egv1a1.BackendList{}
if err := r.client.List(ctx, &backends); err != nil {
return fmt.Errorf("error listing Backends: %w", err)
}
for _, backend := range backends.Items {
- backend := backend
+ backend := backend //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
backend.Status = egv1a1.BackendStatus{}
-
resourceTree.Backends = append(resourceTree.Backends, &backend)
}
return nil
@@ -1021,7 +1157,7 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
// process status updates and infrastructure changes. This step is crucial for synchronizing resources
// that may have been altered or introduced while there was no elected leader.
if err := c.Watch(NewWatchAndReconcileSource(mgr.Elected(), &gwapiv1.GatewayClass{}, handler.EnqueueRequestsFromMapFunc(r.enqueueClass))); err != nil {
- return err
+ return fmt.Errorf("failed to watch GatewayClass: %w", err)
}
if err := c.Watch(
@@ -1031,32 +1167,39 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
}),
&predicate.TypedGenerationChangedPredicate[*gwapiv1.GatewayClass]{},
predicate.NewTypedPredicateFuncs[*gwapiv1.GatewayClass](r.hasMatchingController))); err != nil {
- return err
+ return fmt.Errorf("failed to watch GatewayClass: %w", err)
}
- epPredicates := []predicate.TypedPredicate[*egv1a1.EnvoyProxy]{
- &predicate.TypedGenerationChangedPredicate[*egv1a1.EnvoyProxy]{},
- }
- if r.namespaceLabel != nil {
- epPredicates = append(epPredicates, predicate.NewTypedPredicateFuncs(func(ep *egv1a1.EnvoyProxy) bool {
- return r.hasMatchingNamespaceLabels(ep)
- }))
- }
- if err := c.Watch(
- source.Kind(mgr.GetCache(), &egv1a1.EnvoyProxy{},
- handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, t *egv1a1.EnvoyProxy) []reconcile.Request {
- return r.enqueueClass(ctx, t)
- }),
- epPredicates...)); err != nil {
- return err
- }
- if err := addEnvoyProxyIndexers(ctx, mgr); err != nil {
- return err
+ r.epCRDExists = r.crdExists(mgr, resource.KindEnvoyProxy, egv1a1.GroupVersion.String())
+ if !r.epCRDExists {
+ r.log.Info("EnvoyProxy CRD not found, skipping EnvoyProxy watch")
+ } else {
+ epPredicates := []predicate.TypedPredicate[*egv1a1.EnvoyProxy]{
+ &predicate.TypedGenerationChangedPredicate[*egv1a1.EnvoyProxy]{},
+ }
+ if r.namespaceLabel != nil {
+ epPredicates = append(epPredicates, predicate.NewTypedPredicateFuncs(func(ep *egv1a1.EnvoyProxy) bool {
+ return r.hasMatchingNamespaceLabels(ep)
+ }))
+ }
+
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &egv1a1.EnvoyProxy{},
+ handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, t *egv1a1.EnvoyProxy) []reconcile.Request {
+ return r.enqueueClass(ctx, t)
+ }),
+ epPredicates...)); err != nil {
+ return err
+ }
+ if err := addEnvoyProxyIndexers(ctx, mgr); err != nil {
+ return err
+ }
}
// Watch Gateway CRUDs and reconcile affected GatewayClass.
gPredicates := []predicate.TypedPredicate[*gwapiv1.Gateway]{
- predicate.TypedGenerationChangedPredicate[*gwapiv1.Gateway]{},
+ predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1.Gateway]{},
+ predicate.TypedLabelChangedPredicate[*gwapiv1.Gateway]{}),
predicate.NewTypedPredicateFuncs(func(gtw *gwapiv1.Gateway) bool {
return r.validateGatewayForReconcile(gtw)
}),
@@ -1080,7 +1223,8 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
// Watch HTTPRoute CRUDs and process affected Gateways.
httprPredicates := []predicate.TypedPredicate[*gwapiv1.HTTPRoute]{
- predicate.TypedGenerationChangedPredicate[*gwapiv1.HTTPRoute]{},
+ predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1.HTTPRoute]{},
+ predicate.TypedLabelChangedPredicate[*gwapiv1.HTTPRoute]{}),
}
if r.namespaceLabel != nil {
httprPredicates = append(httprPredicates, predicate.NewTypedPredicateFuncs(func(hr *gwapiv1.HTTPRoute) bool {
@@ -1089,8 +1233,8 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
}
if err := c.Watch(
source.Kind(mgr.GetCache(), &gwapiv1.HTTPRoute{},
- handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, t *gwapiv1.HTTPRoute) []reconcile.Request {
- return r.enqueueClass(ctx, t)
+ handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, route *gwapiv1.HTTPRoute) []reconcile.Request {
+ return r.enqueueClass(ctx, route)
}),
httprPredicates...)); err != nil {
return err
@@ -1099,88 +1243,113 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
return err
}
- // Watch GRPCRoute CRUDs and process affected Gateways.
- grpcrPredicates := []predicate.TypedPredicate[*gwapiv1.GRPCRoute]{
- predicate.TypedGenerationChangedPredicate[*gwapiv1.GRPCRoute]{},
- }
- if r.namespaceLabel != nil {
- grpcrPredicates = append(grpcrPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1.GRPCRoute](func(grpc *gwapiv1.GRPCRoute) bool {
- return r.hasMatchingNamespaceLabels(grpc)
- }))
- }
- if err := c.Watch(
- source.Kind(mgr.GetCache(), &gwapiv1.GRPCRoute{},
- handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1.GRPCRoute](func(ctx context.Context, route *gwapiv1.GRPCRoute) []reconcile.Request {
- return r.enqueueClass(ctx, route)
- }),
- grpcrPredicates...)); err != nil {
- return err
- }
- if err := addGRPCRouteIndexers(ctx, mgr); err != nil {
- return err
+ // TODO: Remove this optional check once most cloud providers and service meshes support GRPCRoute v1
+ r.grpcRouteCRDExists = r.crdExists(mgr, resource.KindGRPCRoute, gwapiv1.GroupVersion.String())
+ if !r.grpcRouteCRDExists {
+ r.log.Info("GRPCRoute CRD not found, skipping GRPCRoute watch")
+ } else {
+ // Watch GRPCRoute CRUDs and process affected Gateways.
+ grpcrPredicates := []predicate.TypedPredicate[*gwapiv1.GRPCRoute]{
+ predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1.GRPCRoute]{},
+ predicate.TypedLabelChangedPredicate[*gwapiv1.GRPCRoute]{}),
+ }
+ if r.namespaceLabel != nil {
+ grpcrPredicates = append(grpcrPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1.GRPCRoute](func(grpc *gwapiv1.GRPCRoute) bool {
+ return r.hasMatchingNamespaceLabels(grpc)
+ }))
+ }
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &gwapiv1.GRPCRoute{},
+ handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1.GRPCRoute](func(ctx context.Context, route *gwapiv1.GRPCRoute) []reconcile.Request {
+ return r.enqueueClass(ctx, route)
+ }),
+ grpcrPredicates...)); err != nil {
+ return err
+ }
+ if err := addGRPCRouteIndexers(ctx, mgr); err != nil {
+ return err
+ }
}
- // Watch TLSRoute CRUDs and process affected Gateways.
- tlsrPredicates := []predicate.TypedPredicate[*gwapiv1a2.TLSRoute]{
- predicate.TypedGenerationChangedPredicate[*gwapiv1a2.TLSRoute]{},
- }
- if r.namespaceLabel != nil {
- tlsrPredicates = append(tlsrPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.TLSRoute](func(route *gwapiv1a2.TLSRoute) bool {
- return r.hasMatchingNamespaceLabels(route)
- }))
- }
- if err := c.Watch(
- source.Kind(mgr.GetCache(), &gwapiv1a2.TLSRoute{},
- handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.TLSRoute](func(ctx context.Context, route *gwapiv1a2.TLSRoute) []reconcile.Request {
- return r.enqueueClass(ctx, route)
- }),
- tlsrPredicates...)); err != nil {
- return err
- }
- if err := addTLSRouteIndexers(ctx, mgr); err != nil {
- return err
+ r.tlsRouteCRDExists = r.crdExists(mgr, resource.KindTLSRoute, gwapiv1a2.GroupVersion.String())
+ if !r.tlsRouteCRDExists {
+ r.log.Info("TLSRoute CRD not found, skipping TLSRoute watch")
+ } else {
+ // Watch TLSRoute CRUDs and process affected Gateways.
+ tlsrPredicates := []predicate.TypedPredicate[*gwapiv1a2.TLSRoute]{
+ predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1a2.TLSRoute]{},
+ predicate.TypedLabelChangedPredicate[*gwapiv1a2.TLSRoute]{}),
+ }
+ if r.namespaceLabel != nil {
+ tlsrPredicates = append(tlsrPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.TLSRoute](func(route *gwapiv1a2.TLSRoute) bool {
+ return r.hasMatchingNamespaceLabels(route)
+ }))
+ }
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &gwapiv1a2.TLSRoute{},
+ handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.TLSRoute](func(ctx context.Context, route *gwapiv1a2.TLSRoute) []reconcile.Request {
+ return r.enqueueClass(ctx, route)
+ }),
+ tlsrPredicates...)); err != nil {
+ return err
+ }
+ if err := addTLSRouteIndexers(ctx, mgr); err != nil {
+ return err
+ }
}
- // Watch UDPRoute CRUDs and process affected Gateways.
- udprPredicates := []predicate.TypedPredicate[*gwapiv1a2.UDPRoute]{
- predicate.TypedGenerationChangedPredicate[*gwapiv1a2.UDPRoute]{},
- }
- if r.namespaceLabel != nil {
- udprPredicates = append(udprPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.UDPRoute](func(route *gwapiv1a2.UDPRoute) bool {
- return r.hasMatchingNamespaceLabels(route)
- }))
- }
- if err := c.Watch(
- source.Kind(mgr.GetCache(), &gwapiv1a2.UDPRoute{},
- handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.UDPRoute](func(ctx context.Context, route *gwapiv1a2.UDPRoute) []reconcile.Request {
- return r.enqueueClass(ctx, route)
- }),
- udprPredicates...)); err != nil {
- return err
- }
- if err := addUDPRouteIndexers(ctx, mgr); err != nil {
- return err
+ r.udpRouteCRDExists = r.crdExists(mgr, resource.KindUDPRoute, gwapiv1a2.GroupVersion.String())
+ if !r.udpRouteCRDExists {
+ r.log.Info("UDPRoute CRD not found, skipping UDPRoute watch")
+ } else {
+ // Watch UDPRoute CRUDs and process affected Gateways.
+ udprPredicates := []predicate.TypedPredicate[*gwapiv1a2.UDPRoute]{
+ predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1a2.UDPRoute]{},
+ predicate.TypedLabelChangedPredicate[*gwapiv1a2.UDPRoute]{}),
+ }
+ if r.namespaceLabel != nil {
+ udprPredicates = append(udprPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.UDPRoute](func(route *gwapiv1a2.UDPRoute) bool {
+ return r.hasMatchingNamespaceLabels(route)
+ }))
+ }
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &gwapiv1a2.UDPRoute{},
+ handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.UDPRoute](func(ctx context.Context, route *gwapiv1a2.UDPRoute) []reconcile.Request {
+ return r.enqueueClass(ctx, route)
+ }),
+ udprPredicates...)); err != nil {
+ return err
+ }
+ if err := addUDPRouteIndexers(ctx, mgr); err != nil {
+ return err
+ }
}
- // Watch TCPRoute CRUDs and process affected Gateways.
- tcprPredicates := []predicate.TypedPredicate[*gwapiv1a2.TCPRoute]{
- predicate.TypedGenerationChangedPredicate[*gwapiv1a2.TCPRoute]{},
- }
- if r.namespaceLabel != nil {
- tcprPredicates = append(tcprPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.TCPRoute](func(route *gwapiv1a2.TCPRoute) bool {
- return r.hasMatchingNamespaceLabels(route)
- }))
- }
- if err := c.Watch(
- source.Kind(mgr.GetCache(), &gwapiv1a2.TCPRoute{},
- handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.TCPRoute](func(ctx context.Context, route *gwapiv1a2.TCPRoute) []reconcile.Request {
- return r.enqueueClass(ctx, route)
- }),
- tcprPredicates...)); err != nil {
- return err
- }
- if err := addTCPRouteIndexers(ctx, mgr); err != nil {
- return err
+ r.tcpRouteCRDExists = r.crdExists(mgr, resource.KindTCPRoute, gwapiv1a2.GroupVersion.String())
+ if !r.tcpRouteCRDExists {
+ r.log.Info("TCPRoute CRD not found, skipping TCPRoute watch")
+ } else {
+ // Watch TCPRoute CRUDs and process affected Gateways.
+ tcprPredicates := []predicate.TypedPredicate[*gwapiv1a2.TCPRoute]{
+ predicate.Or(predicate.TypedGenerationChangedPredicate[*gwapiv1a2.TCPRoute]{},
+ predicate.TypedLabelChangedPredicate[*gwapiv1a2.TCPRoute]{}),
+ }
+ if r.namespaceLabel != nil {
+ tcprPredicates = append(tcprPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.TCPRoute](func(route *gwapiv1a2.TCPRoute) bool {
+ return r.hasMatchingNamespaceLabels(route)
+ }))
+ }
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &gwapiv1a2.TCPRoute{},
+ handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.TCPRoute](func(ctx context.Context, route *gwapiv1a2.TCPRoute) []reconcile.Request {
+ return r.enqueueClass(ctx, route)
+ }),
+ tcprPredicates...)); err != nil {
+ return err
+ }
+ if err := addTCPRouteIndexers(ctx, mgr); err != nil {
+ return err
+ }
}
// Watch Service CRUDs and process affected *Route objects.
@@ -1203,13 +1372,11 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
return err
}
- serviceImportCRDExists := r.serviceImportCRDExists(mgr)
- if !serviceImportCRDExists {
- r.log.Info("ServiceImport CRD not found, skipping ServiceImport watch")
- }
-
// Watch ServiceImport CRUDs and process affected *Route objects.
- if serviceImportCRDExists {
+ r.serviceImportCRDExists = r.crdExists(mgr, resource.KindServiceImport, mcsapiv1a1.GroupVersion.String())
+ if !r.serviceImportCRDExists {
+ r.log.Info("ServiceImport CRD not found, skipping ServiceImport watch")
+ } else {
if err := c.Watch(
source.Kind(mgr.GetCache(), &mcsapiv1a1.ServiceImport{},
handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, si *mcsapiv1a1.ServiceImport) []reconcile.Request {
@@ -1245,8 +1412,11 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
return err
}
- // Watch Backend CRUDs and process affected *Route objects.
- if r.envoyGateway.ExtensionAPIs != nil && r.envoyGateway.ExtensionAPIs.EnableBackend {
+ r.backendCRDExists = r.crdExists(mgr, resource.KindBackend, egv1a1.GroupVersion.String())
+ if !r.backendCRDExists {
+ r.log.Info("Backend CRD not found, skipping Backend watch")
+ } else if r.envoyGateway.ExtensionAPIs != nil && r.envoyGateway.ExtensionAPIs.EnableBackend {
+ // Watch Backend CRUDs and process affected *Route objects.
backendPredicates := []predicate.TypedPredicate[*egv1a1.Backend]{
predicate.TypedGenerationChangedPredicate[*egv1a1.Backend]{},
predicate.NewTypedPredicateFuncs[*egv1a1.Backend](func(be *egv1a1.Backend) bool {
@@ -1311,7 +1481,7 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
return err
}
- // Watch ConfigMap CRUDs and process affected ClienTraffiPolicies and BackendTLSPolicies.
+ // Watch ConfigMap CRUDs and process affected EG Resources.
configMapPredicates := []predicate.TypedPredicate[*corev1.ConfigMap]{
predicate.NewTypedPredicateFuncs[*corev1.ConfigMap](func(cm *corev1.ConfigMap) bool {
return r.validateConfigMapForReconcile(cm)
@@ -1353,13 +1523,13 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
}
// Watch Deployment CRUDs and process affected Gateways.
- dPredicates := []predicate.TypedPredicate[*appsv1.Deployment]{
+ deploymentPredicates := []predicate.TypedPredicate[*appsv1.Deployment]{
predicate.NewTypedPredicateFuncs[*appsv1.Deployment](func(deploy *appsv1.Deployment) bool {
- return r.validateDeploymentForReconcile(deploy)
+ return r.validateObjectForReconcile(deploy)
}),
}
if r.namespaceLabel != nil {
- dPredicates = append(dPredicates, predicate.NewTypedPredicateFuncs[*appsv1.Deployment](func(deploy *appsv1.Deployment) bool {
+ deploymentPredicates = append(deploymentPredicates, predicate.NewTypedPredicateFuncs[*appsv1.Deployment](func(deploy *appsv1.Deployment) bool {
return r.hasMatchingNamespaceLabels(deploy)
}))
}
@@ -1368,11 +1538,34 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, deploy *appsv1.Deployment) []reconcile.Request {
return r.enqueueClass(ctx, deploy)
}),
- dPredicates...)); err != nil {
+ deploymentPredicates...)); err != nil {
+ return err
+ }
+
+ // Watch DaemonSet CRUDs and process affected Gateways.
+ daemonsetPredicates := []predicate.TypedPredicate[*appsv1.DaemonSet]{
+ predicate.NewTypedPredicateFuncs[*appsv1.DaemonSet](func(daemonset *appsv1.DaemonSet) bool {
+ return r.validateObjectForReconcile(daemonset)
+ }),
+ }
+ if r.namespaceLabel != nil {
+ daemonsetPredicates = append(daemonsetPredicates, predicate.NewTypedPredicateFuncs[*appsv1.DaemonSet](func(daemonset *appsv1.DaemonSet) bool {
+ return r.hasMatchingNamespaceLabels(daemonset)
+ }))
+ }
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &appsv1.DaemonSet{},
+ handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, daemonset *appsv1.DaemonSet) []reconcile.Request {
+ return r.enqueueClass(ctx, daemonset)
+ }),
+ daemonsetPredicates...)); err != nil {
return err
}
- if r.envoyGateway.ExtensionAPIs != nil && r.envoyGateway.ExtensionAPIs.EnableEnvoyPatchPolicy {
+ r.eppCRDExists = r.crdExists(mgr, resource.KindEnvoyPatchPolicy, egv1a1.GroupVersion.String())
+ if !r.eppCRDExists {
+ r.log.Info("EnvoyPatchPolicy CRD not found, skipping EnvoyPatchPolicy watch")
+ } else if r.envoyGateway.ExtensionAPIs != nil && r.envoyGateway.ExtensionAPIs.EnableEnvoyPatchPolicy {
// Watch EnvoyPatchPolicy if enabled in config
eppPredicates := []predicate.TypedPredicate[*egv1a1.EnvoyPatchPolicy]{
predicate.TypedGenerationChangedPredicate[*egv1a1.EnvoyPatchPolicy]{},
@@ -1393,114 +1586,143 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
}
}
- // Watch ClientTrafficPolicy
- ctpPredicates := []predicate.TypedPredicate[*egv1a1.ClientTrafficPolicy]{
- predicate.TypedGenerationChangedPredicate[*egv1a1.ClientTrafficPolicy]{},
- }
- if r.namespaceLabel != nil {
- ctpPredicates = append(ctpPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.ClientTrafficPolicy](func(ctp *egv1a1.ClientTrafficPolicy) bool {
- return r.hasMatchingNamespaceLabels(ctp)
- }))
- }
+ r.ctpCRDExists = r.crdExists(mgr, resource.KindClientTrafficPolicy, egv1a1.GroupVersion.String())
+ if !r.ctpCRDExists {
+ r.log.Info("ClientTrafficPolicy CRD not found, skipping ClientTrafficPolicy watch")
+ } else {
+ // Watch ClientTrafficPolicy
+ ctpPredicates := []predicate.TypedPredicate[*egv1a1.ClientTrafficPolicy]{
+ predicate.TypedGenerationChangedPredicate[*egv1a1.ClientTrafficPolicy]{},
+ }
+ if r.namespaceLabel != nil {
+ ctpPredicates = append(ctpPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.ClientTrafficPolicy](func(ctp *egv1a1.ClientTrafficPolicy) bool {
+ return r.hasMatchingNamespaceLabels(ctp)
+ }))
+ }
- if err := c.Watch(
- source.Kind(mgr.GetCache(), &egv1a1.ClientTrafficPolicy{},
- handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, ctp *egv1a1.ClientTrafficPolicy) []reconcile.Request {
- return r.enqueueClass(ctx, ctp)
- }),
- ctpPredicates...)); err != nil {
- return err
- }
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &egv1a1.ClientTrafficPolicy{},
+ handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, ctp *egv1a1.ClientTrafficPolicy) []reconcile.Request {
+ return r.enqueueClass(ctx, ctp)
+ }),
+ ctpPredicates...)); err != nil {
+ return err
+ }
- if err := addCtpIndexers(ctx, mgr); err != nil {
- return err
+ if err := addCtpIndexers(ctx, mgr); err != nil {
+ return err
+ }
}
- // Watch BackendTrafficPolicy
- btpPredicates := []predicate.TypedPredicate[*egv1a1.BackendTrafficPolicy]{
- predicate.TypedGenerationChangedPredicate[*egv1a1.BackendTrafficPolicy]{},
- }
- if r.namespaceLabel != nil {
- btpPredicates = append(btpPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.BackendTrafficPolicy](func(btp *egv1a1.BackendTrafficPolicy) bool {
- return r.hasMatchingNamespaceLabels(btp)
- }))
- }
+ r.btpCRDExists = r.crdExists(mgr, resource.KindBackendTrafficPolicy, egv1a1.GroupVersion.String())
+ if !r.btpCRDExists {
+ r.log.Info("BackendTrafficPolicy CRD not found, skipping BackendTrafficPolicy watch")
+ } else {
+ // Watch BackendTrafficPolicy
+ btpPredicates := []predicate.TypedPredicate[*egv1a1.BackendTrafficPolicy]{
+ predicate.TypedGenerationChangedPredicate[*egv1a1.BackendTrafficPolicy]{},
+ }
+ if r.namespaceLabel != nil {
+ btpPredicates = append(btpPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.BackendTrafficPolicy](func(btp *egv1a1.BackendTrafficPolicy) bool {
+ return r.hasMatchingNamespaceLabels(btp)
+ }))
+ }
- if err := c.Watch(
- source.Kind(mgr.GetCache(), &egv1a1.BackendTrafficPolicy{},
- handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *egv1a1.BackendTrafficPolicy) []reconcile.Request {
- return r.enqueueClass(ctx, btp)
- }),
- btpPredicates...)); err != nil {
- return err
- }
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &egv1a1.BackendTrafficPolicy{},
+ handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *egv1a1.BackendTrafficPolicy) []reconcile.Request {
+ return r.enqueueClass(ctx, btp)
+ }),
+ btpPredicates...)); err != nil {
+ return err
+ }
- // Watch SecurityPolicy
- spPredicates := []predicate.TypedPredicate[*egv1a1.SecurityPolicy]{
- predicate.TypedGenerationChangedPredicate[*egv1a1.SecurityPolicy]{},
- }
- if r.namespaceLabel != nil {
- spPredicates = append(spPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.SecurityPolicy](func(sp *egv1a1.SecurityPolicy) bool {
- return r.hasMatchingNamespaceLabels(sp)
- }))
+ if err := addBtpIndexers(ctx, mgr); err != nil {
+ return err
+ }
}
- if err := c.Watch(
- source.Kind(mgr.GetCache(), &egv1a1.SecurityPolicy{},
- handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, sp *egv1a1.SecurityPolicy) []reconcile.Request {
- return r.enqueueClass(ctx, sp)
- }),
- spPredicates...)); err != nil {
- return err
- }
- if err := addSecurityPolicyIndexers(ctx, mgr); err != nil {
- return err
- }
+ r.spCRDExists = r.crdExists(mgr, resource.KindSecurityPolicy, egv1a1.GroupVersion.String())
+ if !r.spCRDExists {
+ r.log.Info("SecurityPolicy CRD not found, skipping SecurityPolicy watch")
+ } else {
+ // Watch SecurityPolicy
+ spPredicates := []predicate.TypedPredicate[*egv1a1.SecurityPolicy]{
+ predicate.TypedGenerationChangedPredicate[*egv1a1.SecurityPolicy]{},
+ }
+ if r.namespaceLabel != nil {
+ spPredicates = append(spPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.SecurityPolicy](func(sp *egv1a1.SecurityPolicy) bool {
+ return r.hasMatchingNamespaceLabels(sp)
+ }))
+ }
- // Watch BackendTLSPolicy
- btlsPredicates := []predicate.TypedPredicate[*gwapiv1a3.BackendTLSPolicy]{
- predicate.TypedGenerationChangedPredicate[*gwapiv1a3.BackendTLSPolicy]{},
- }
- if r.namespaceLabel != nil {
- btlsPredicates = append(btlsPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a3.BackendTLSPolicy](func(btp *gwapiv1a3.BackendTLSPolicy) bool {
- return r.hasMatchingNamespaceLabels(btp)
- }))
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &egv1a1.SecurityPolicy{},
+ handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, sp *egv1a1.SecurityPolicy) []reconcile.Request {
+ return r.enqueueClass(ctx, sp)
+ }),
+ spPredicates...)); err != nil {
+ return err
+ }
+ if err := addSecurityPolicyIndexers(ctx, mgr); err != nil {
+ return err
+ }
}
- if err := c.Watch(
- source.Kind(mgr.GetCache(), &gwapiv1a3.BackendTLSPolicy{},
- handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *gwapiv1a3.BackendTLSPolicy) []reconcile.Request {
- return r.enqueueClass(ctx, btp)
- }),
- btlsPredicates...)); err != nil {
- return err
- }
+ r.bTLSPolicyCRDExists = r.crdExists(mgr, resource.KindBackendTLSPolicy, gwapiv1a3.GroupVersion.String())
+ if !r.bTLSPolicyCRDExists {
+ r.log.Info("BackendTLSPolicy CRD not found, skipping BackendTLSPolicy watch")
+ } else {
+ // Watch BackendTLSPolicy
+ btlsPredicates := []predicate.TypedPredicate[*gwapiv1a3.BackendTLSPolicy]{
+ predicate.TypedGenerationChangedPredicate[*gwapiv1a3.BackendTLSPolicy]{},
+ }
+ if r.namespaceLabel != nil {
+ btlsPredicates = append(btlsPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a3.BackendTLSPolicy](func(btp *gwapiv1a3.BackendTLSPolicy) bool {
+ return r.hasMatchingNamespaceLabels(btp)
+ }))
+ }
- if err := addBtlsIndexers(ctx, mgr); err != nil {
- return err
- }
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &gwapiv1a3.BackendTLSPolicy{},
+ handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *gwapiv1a3.BackendTLSPolicy) []reconcile.Request {
+ return r.enqueueClass(ctx, btp)
+ }),
+ btlsPredicates...)); err != nil {
+ return err
+ }
- // Watch EnvoyExtensionPolicy
- eepPredicates := []predicate.TypedPredicate[*egv1a1.EnvoyExtensionPolicy]{
- predicate.TypedGenerationChangedPredicate[*egv1a1.EnvoyExtensionPolicy]{},
- }
- if r.namespaceLabel != nil {
- eepPredicates = append(eepPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.EnvoyExtensionPolicy](func(eep *egv1a1.EnvoyExtensionPolicy) bool {
- return r.hasMatchingNamespaceLabels(eep)
- }))
+ if err := addBtlsIndexers(ctx, mgr); err != nil {
+ return err
+ }
}
- // Watch EnvoyExtensionPolicy CRUDs
- if err := c.Watch(
- source.Kind(mgr.GetCache(), &egv1a1.EnvoyExtensionPolicy{},
- handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, eep *egv1a1.EnvoyExtensionPolicy) []reconcile.Request {
- return r.enqueueClass(ctx, eep)
- }),
- eepPredicates...)); err != nil {
- return err
- }
- if err := addEnvoyExtensionPolicyIndexers(ctx, mgr); err != nil {
- return err
+ r.eepCRDExists = r.crdExists(mgr, resource.KindEnvoyExtensionPolicy, egv1a1.GroupVersion.String())
+ if !r.eepCRDExists {
+ r.log.Info("EnvoyExtensionPolicy CRD not found, skipping EnvoyExtensionPolicy watch")
+ } else {
+ // Watch EnvoyExtensionPolicy
+ eepPredicates := []predicate.TypedPredicate[*egv1a1.EnvoyExtensionPolicy]{
+ predicate.TypedGenerationChangedPredicate[*egv1a1.EnvoyExtensionPolicy]{},
+ }
+ if r.namespaceLabel != nil {
+ eepPredicates = append(eepPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.EnvoyExtensionPolicy](func(eep *egv1a1.EnvoyExtensionPolicy) bool {
+ return r.hasMatchingNamespaceLabels(eep)
+ }))
+ }
+
+ // Watch EnvoyExtensionPolicy CRUDs
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &egv1a1.EnvoyExtensionPolicy{},
+ handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, eep *egv1a1.EnvoyExtensionPolicy) []reconcile.Request {
+ return r.enqueueClass(ctx, eep)
+ }),
+ eepPredicates...)); err != nil {
+ return err
+ }
+ if err := addEnvoyExtensionPolicyIndexers(ctx, mgr); err != nil {
+ return err
+ }
}
r.log.Info("Watching gatewayAPI related objects")
@@ -1539,6 +1761,35 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
r.log.Info("Watching additional policy resource", "resource", gvk.String())
}
+ r.hrfCRDExists = r.crdExists(mgr, resource.KindHTTPRouteFilter, egv1a1.GroupVersion.String())
+ if !r.hrfCRDExists {
+ r.log.Info("HTTPRouteFilter CRD not found, skipping HTTPRouteFilter watch")
+ } else {
+ // Watch HTTPRouteFilter CRUDs and process affected HTTPRoute objects.
+ httpRouteFilter := []predicate.TypedPredicate[*egv1a1.HTTPRouteFilter]{
+ predicate.TypedGenerationChangedPredicate[*egv1a1.HTTPRouteFilter]{},
+ predicate.NewTypedPredicateFuncs[*egv1a1.HTTPRouteFilter](func(be *egv1a1.HTTPRouteFilter) bool {
+ return r.validateHTTPRouteFilterForReconcile(be)
+ }),
+ }
+ if r.namespaceLabel != nil {
+ httpRouteFilter = append(httpRouteFilter, predicate.NewTypedPredicateFuncs[*egv1a1.HTTPRouteFilter](func(be *egv1a1.HTTPRouteFilter) bool {
+ return r.hasMatchingNamespaceLabels(be)
+ }))
+ }
+ if err := c.Watch(
+ source.Kind(mgr.GetCache(), &egv1a1.HTTPRouteFilter{},
+ handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, be *egv1a1.HTTPRouteFilter) []reconcile.Request {
+ return r.enqueueClass(ctx, be)
+ }),
+ httpRouteFilter...)); err != nil {
+ return err
+ }
+
+ if err := addRouteFilterIndexers(ctx, mgr); err != nil {
+ return err
+ }
+ }
return nil
}
@@ -1549,7 +1800,7 @@ func (r *gatewayAPIReconciler) enqueueClass(_ context.Context, _ client.Object)
}
// processGatewayParamsRef processes the infrastructure.parametersRef of the provided Gateway.
-func (r *gatewayAPIReconciler) processGatewayParamsRef(ctx context.Context, gtw *gwapiv1.Gateway, resourceMap *resourceMappings, resourceTree *gatewayapi.Resources) error {
+func (r *gatewayAPIReconciler) processGatewayParamsRef(ctx context.Context, gtw *gwapiv1.Gateway, resourceMap *resourceMappings, resourceTree *resource.Resources) error {
if gtw == nil || gtw.Spec.Infrastructure == nil || gtw.Spec.Infrastructure.ParametersRef == nil {
return nil
}
@@ -1581,7 +1832,7 @@ func (r *gatewayAPIReconciler) processGatewayParamsRef(ctx context.Context, gtw
ctx,
resourceMap,
resourceTree,
- gatewayapi.KindGateway,
+ resource.KindGateway,
gtw.Namespace,
gtw.Name,
*certRef); err != nil {
@@ -1597,7 +1848,7 @@ func (r *gatewayAPIReconciler) processGatewayParamsRef(ctx context.Context, gtw
}
// processGatewayClassParamsRef processes the parametersRef of the provided GatewayClass.
-func (r *gatewayAPIReconciler) processGatewayClassParamsRef(ctx context.Context, gc *gwapiv1.GatewayClass, resourceMap *resourceMappings, resourceTree *gatewayapi.Resources) error {
+func (r *gatewayAPIReconciler) processGatewayClassParamsRef(ctx context.Context, gc *gwapiv1.GatewayClass, resourceMap *resourceMappings, resourceTree *resource.Resources) error {
if !refsEnvoyProxy(gc) {
return fmt.Errorf("unsupported parametersRef for gatewayclass %s", gc.Name)
}
@@ -1630,6 +1881,9 @@ func (r *gatewayAPIReconciler) processEnvoyProxy(ep *egv1a1.EnvoyProxy, resource
if err := validation.ValidateEnvoyProxy(ep); err != nil {
return fmt.Errorf("invalid envoyproxy: %w", err)
}
+ if err := bootstrap.Validate(ep.Spec.Bootstrap); err != nil {
+ return fmt.Errorf("invalid envoyproxy: %w", err)
+ }
if ep.Spec.Telemetry != nil {
var backendRefs []egv1a1.BackendRef
@@ -1675,8 +1929,8 @@ func (r *gatewayAPIReconciler) processEnvoyProxy(ep *egv1a1.EnvoyProxy, resource
return nil
}
-// serviceImportCRDExists checks for the existence of the ServiceImport CRD in k8s APIServer before watching it
-func (r *gatewayAPIReconciler) serviceImportCRDExists(mgr manager.Manager) bool {
+// crdExists checks for the existence of the CRD in k8s APIServer before watching it
+func (r *gatewayAPIReconciler) crdExists(mgr manager.Manager, kind string, groupVersion string) bool {
discoveryClient, err := discovery.NewDiscoveryClientForConfig(mgr.GetConfig())
if err != nil {
r.log.Error(err, "failed to create discovery client")
@@ -1685,22 +1939,22 @@ func (r *gatewayAPIReconciler) serviceImportCRDExists(mgr manager.Manager) bool
if err != nil {
r.log.Error(err, "failed to get API resource list")
}
- serviceImportFound := false
+ found := false
for _, list := range apiResourceList {
- for _, resource := range list.APIResources {
- if list.GroupVersion == mcsapiv1a1.GroupVersion.String() && resource.Kind == gatewayapi.KindServiceImport {
- serviceImportFound = true
+ for _, res := range list.APIResources {
+ if list.GroupVersion == groupVersion && res.Kind == kind {
+ found = true
break
}
}
}
- return serviceImportFound
+ return found
}
func (r *gatewayAPIReconciler) processBackendTLSPolicyRefs(
ctx context.Context,
- resourceTree *gatewayapi.Resources,
+ resourceTree *resource.Resources,
resourceMap *resourceMappings,
) {
for _, policy := range resourceTree.BackendTLSPolicies {
@@ -1709,33 +1963,33 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicyRefs(
if tls.CACertificateRefs != nil {
for _, caCertRef := range tls.CACertificateRefs {
// if kind is not Secret or ConfigMap, we skip early to avoid further calculation overhead
- if string(caCertRef.Kind) == gatewayapi.KindConfigMap ||
- string(caCertRef.Kind) == gatewayapi.KindSecret {
+ if string(caCertRef.Kind) == resource.KindConfigMap ||
+ string(caCertRef.Kind) == resource.KindSecret {
var err error
- caRefNew := gwapiv1b1.SecretObjectReference{
+ caRefNew := gwapiv1.SecretObjectReference{
Group: gatewayapi.GroupPtr(string(caCertRef.Group)),
Kind: gatewayapi.KindPtr(string(caCertRef.Kind)),
Name: caCertRef.Name,
Namespace: gatewayapi.NamespacePtr(policy.Namespace),
}
switch string(caCertRef.Kind) {
- case gatewayapi.KindConfigMap:
+ case resource.KindConfigMap:
err = r.processConfigMapRef(
ctx,
resourceMap,
resourceTree,
- gatewayapi.KindBackendTLSPolicy,
+ resource.KindBackendTLSPolicy,
policy.Namespace,
policy.Name,
caRefNew)
- case gatewayapi.KindSecret:
+ case resource.KindSecret:
err = r.processSecretRef(
ctx,
resourceMap,
resourceTree,
- gatewayapi.KindBackendTLSPolicy,
+ resource.KindBackendTLSPolicy,
policy.Namespace,
policy.Name,
caRefNew)
@@ -1759,7 +2013,7 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicyRefs(
// processEnvoyExtensionPolicies adds EnvoyExtensionPolicies and their referenced resources to the resourceTree
func (r *gatewayAPIReconciler) processEnvoyExtensionPolicies(
- ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings,
+ ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings,
) error {
envoyExtensionPolicies := egv1a1.EnvoyExtensionPolicyList{}
if err := r.client.List(ctx, &envoyExtensionPolicies); err != nil {
@@ -1767,11 +2021,14 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicies(
}
for _, policy := range envoyExtensionPolicies.Items {
- policy := policy
+ envoyExtensionPolicy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
- policy.Status = gwapiv1a2.PolicyStatus{}
- resourceTree.EnvoyExtensionPolicies = append(resourceTree.EnvoyExtensionPolicies, &policy)
+ envoyExtensionPolicy.Status = gwapiv1a2.PolicyStatus{}
+ if !resourceMap.allAssociatedEnvoyExtensionPolicies.Has(utils.NamespacedName(&envoyExtensionPolicy).String()) {
+ resourceMap.allAssociatedEnvoyExtensionPolicies.Insert(utils.NamespacedName(&envoyExtensionPolicy).String())
+ resourceTree.EnvoyExtensionPolicies = append(resourceTree.EnvoyExtensionPolicies, &envoyExtensionPolicy)
+ }
}
// Add the referenced Resources in EnvoyExtensionPolicies to the resourceTree
@@ -1782,7 +2039,7 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicies(
// processExtensionServerPolicies adds directly attached policies intended for the extension server
func (r *gatewayAPIReconciler) processExtensionServerPolicies(
- ctx context.Context, resourceTree *gatewayapi.Resources,
+ ctx context.Context, resourceTree *resource.Resources,
) error {
for _, gvk := range r.extServerPolicies {
polList := unstructured.UnstructuredList{}
@@ -1794,8 +2051,6 @@ func (r *gatewayAPIReconciler) processExtensionServerPolicies(
}
for _, policy := range polList.Items {
- policy := policy
-
policySpec, found := policy.Object["spec"].(map[string]any)
if !found {
return fmt.Errorf("no spec found in %s.%s %s", policy.GetAPIVersion(), policy.GetKind(), policy.GetName())
@@ -1820,7 +2075,7 @@ func (r *gatewayAPIReconciler) processExtensionServerPolicies(
// - BackendRefs for ExtProcs
// - SecretRefs for Wasms
func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs(
- ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings,
+ ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings,
) {
// we don't return errors from this method, because we want to continue reconciling
// the rest of the EnvoyExtensionPolicies despite that one reference is invalid. This
@@ -1845,12 +2100,12 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs(
if backendNamespace != policy.Namespace {
from := ObjectKindNamespacedName{
- kind: gatewayapi.KindHTTPRoute,
+ kind: resource.KindEnvoyExtensionPolicy,
namespace: policy.Namespace,
name: policy.Name,
}
to := ObjectKindNamespacedName{
- kind: gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService),
+ kind: gatewayapi.KindDerefOr(backendRef.Kind, resource.KindService),
namespace: backendNamespace,
name: string(backendRef.Name),
}
@@ -1862,9 +2117,12 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs(
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
- resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
- r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
- "name", refGrant.Name)
+ if !resourceMap.allAssociatedReferenceGrants.Has(utils.NamespacedName(refGrant).String()) {
+ resourceMap.allAssociatedReferenceGrants.Insert(utils.NamespacedName(refGrant).String())
+ resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
+ r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
+ "name", refGrant.Name)
+ }
}
}
}
@@ -1877,7 +2135,7 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs(
ctx,
resourceMap,
resourceTree,
- gatewayapi.KindSecurityPolicy,
+ resource.KindSecurityPolicy,
policy.Namespace,
policy.Name,
*wasm.Code.Image.PullSecretRef); err != nil {
diff --git a/internal/provider/kubernetes/controller_test.go b/internal/provider/kubernetes/controller_test.go
index e3b63360163..d008e7b2f70 100644
--- a/internal/provider/kubernetes/controller_test.go
+++ b/internal/provider/kubernetes/controller_test.go
@@ -12,13 +12,16 @@ import (
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+ gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/logging"
)
@@ -73,7 +76,6 @@ func TestAddGatewayClassFinalizer(t *testing.T) {
ctx := context.Background()
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
r.client = fakeclient.NewClientBuilder().WithScheme(envoygateway.GetScheme()).WithObjects(tc.gc).Build()
err := r.addFinalizer(ctx, tc.gc)
@@ -137,7 +139,6 @@ func TestRemoveGatewayClassFinalizer(t *testing.T) {
ctx := context.Background()
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
r.client = fakeclient.NewClientBuilder().WithScheme(envoygateway.GetScheme()).WithObjects(tc.gc).Build()
err := r.removeFinalizer(ctx, tc.gc)
@@ -276,7 +277,7 @@ func TestProcessGatewayClassParamsRef(t *testing.T) {
}
// Process the test case gatewayclasses.
- resourceTree := gatewayapi.NewResources()
+ resourceTree := resource.NewResources()
resourceMap := newResourceMapping()
err := r.processGatewayClassParamsRef(context.Background(), tc.gc, resourceMap, resourceTree)
if tc.expected {
@@ -289,3 +290,162 @@ func TestProcessGatewayClassParamsRef(t *testing.T) {
})
}
}
+
+func TestProcessEnvoyExtensionPolicyObjectRefs(t *testing.T) {
+ testCases := []struct {
+ name string
+ envoyExtensionPolicy *egv1a1.EnvoyExtensionPolicy
+ backend *egv1a1.Backend
+ referenceGrant *gwapiv1b1.ReferenceGrant
+ shouldBeAdded bool
+ }{
+ {
+ name: "valid envoy extension policy with proper ref grant to backend",
+ envoyExtensionPolicy: &egv1a1.EnvoyExtensionPolicy{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns-1",
+ Name: "test-policy",
+ },
+ Spec: egv1a1.EnvoyExtensionPolicySpec{
+ ExtProc: []egv1a1.ExtProc{
+ {
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Namespace: gatewayapi.NamespacePtr("ns-2"),
+ Name: "test-backend",
+ Kind: gatewayapi.KindPtr(resource.KindBackend),
+ Group: gatewayapi.GroupPtr(egv1a1.GroupName),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ backend: &egv1a1.Backend{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns-2",
+ Name: "test-backend",
+ },
+ },
+ referenceGrant: &gwapiv1b1.ReferenceGrant{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns-2",
+ Name: "test-grant",
+ },
+ Spec: gwapiv1b1.ReferenceGrantSpec{
+ From: []gwapiv1b1.ReferenceGrantFrom{
+ {
+ Namespace: gwapiv1.Namespace("ns-1"),
+ Kind: gwapiv1.Kind(resource.KindEnvoyExtensionPolicy),
+ Group: gwapiv1.Group(egv1a1.GroupName),
+ },
+ },
+ To: []gwapiv1b1.ReferenceGrantTo{
+ {
+ Name: gatewayapi.ObjectNamePtr("test-backend"),
+ Kind: gwapiv1.Kind(resource.KindBackend),
+ Group: gwapiv1.Group(egv1a1.GroupName),
+ },
+ },
+ },
+ },
+ shouldBeAdded: true,
+ },
+ {
+ name: "valid envoy extension policy with wrong from kind in ref grant to backend",
+ envoyExtensionPolicy: &egv1a1.EnvoyExtensionPolicy{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns-1",
+ Name: "test-policy",
+ },
+ Spec: egv1a1.EnvoyExtensionPolicySpec{
+ ExtProc: []egv1a1.ExtProc{
+ {
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Namespace: gatewayapi.NamespacePtr("ns-2"),
+ Name: "test-backend",
+ Kind: gatewayapi.KindPtr(resource.KindBackend),
+ Group: gatewayapi.GroupPtr(egv1a1.GroupName),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ backend: &egv1a1.Backend{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns-2",
+ Name: "test-backend",
+ },
+ },
+ referenceGrant: &gwapiv1b1.ReferenceGrant{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns-2",
+ Name: "test-grant",
+ },
+ Spec: gwapiv1b1.ReferenceGrantSpec{
+ From: []gwapiv1b1.ReferenceGrantFrom{
+ {
+ Namespace: gwapiv1.Namespace("ns-1"),
+ Kind: gwapiv1.Kind(resource.KindHTTPRoute),
+ Group: gwapiv1.Group(gwapiv1.GroupName),
+ },
+ },
+ To: []gwapiv1b1.ReferenceGrantTo{
+ {
+ Name: gatewayapi.ObjectNamePtr("test-backend"),
+ Kind: gwapiv1.Kind(resource.KindBackend),
+ Group: gwapiv1.Group(egv1a1.GroupName),
+ },
+ },
+ },
+ },
+ shouldBeAdded: false,
+ },
+ }
+
+ for i := range testCases {
+ tc := testCases[i]
+ // Run the test cases.
+ t.Run(tc.name, func(t *testing.T) {
+ // Add objects referenced by test cases.
+ objs := []client.Object{tc.envoyExtensionPolicy, tc.backend, tc.referenceGrant}
+
+ // Create the reconciler.
+ logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+
+ ctx := context.Background()
+
+ r := &gatewayAPIReconciler{
+ log: logger,
+ classController: "some-gateway-class",
+ }
+
+ r.client = fakeclient.NewClientBuilder().
+ WithScheme(envoygateway.GetScheme()).
+ WithObjects(objs...).
+ WithIndex(&gwapiv1b1.ReferenceGrant{}, targetRefGrantRouteIndex, getReferenceGrantIndexerFunc()).
+ Build()
+
+ resourceTree := resource.NewResources()
+ resourceMap := newResourceMapping()
+
+ err := r.processEnvoyExtensionPolicies(ctx, resourceTree, resourceMap)
+ require.NoError(t, err)
+ if tc.shouldBeAdded {
+ require.Contains(t, resourceTree.ReferenceGrants, tc.referenceGrant)
+ } else {
+ require.NotContains(t, resourceTree.ReferenceGrants, tc.referenceGrant)
+ }
+ })
+ }
+}
diff --git a/internal/provider/kubernetes/extensionpolicies_test.go b/internal/provider/kubernetes/extensionpolicies_test.go
index dbfb2904ffa..3d74ff270df 100644
--- a/internal/provider/kubernetes/extensionpolicies_test.go
+++ b/internal/provider/kubernetes/extensionpolicies_test.go
@@ -17,7 +17,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway"
- "github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/logging"
)
@@ -226,7 +226,7 @@ func TestProcessExtensionPolicies(t *testing.T) {
WithObjects(objs...).
Build()
- resourceTree := gatewayapi.NewResources()
+ resourceTree := resource.NewResources()
err := r.processExtensionServerPolicies(ctx, resourceTree)
if !tc.errorExpected {
require.NoError(t, err)
diff --git a/internal/provider/kubernetes/filters.go b/internal/provider/kubernetes/filters.go
index 8ef8dc1ede1..cffcf214f6b 100644
--- a/internal/provider/kubernetes/filters.go
+++ b/internal/provider/kubernetes/filters.go
@@ -9,7 +9,13 @@ import (
"context"
"fmt"
+ corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/types"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
+ "github.com/envoyproxy/gateway/internal/utils"
)
func (r *gatewayAPIReconciler) getExtensionRefFilters(ctx context.Context) ([]unstructured.Unstructured, error) {
@@ -26,7 +32,6 @@ func (r *gatewayAPIReconciler) getExtensionRefFilters(ctx context.Context) ([]un
if r.namespaceLabel != nil {
var extRs []unstructured.Unstructured
for _, extR := range uExtResources {
- extR := extR
ok, err := r.checkObjectNamespaceLabels(&extR)
if err != nil {
r.log.Error(err, "failed to check namespace labels for ExtensionRefFilter %s in namespace %s: %w", extR.GetName(), extR.GetNamespace())
@@ -44,3 +49,47 @@ func (r *gatewayAPIReconciler) getExtensionRefFilters(ctx context.Context) ([]un
return resourceItems, nil
}
+
+func (r *gatewayAPIReconciler) getHTTPRouteFilters(ctx context.Context) ([]egv1a1.HTTPRouteFilter, error) {
+ httpFilterList := new(egv1a1.HTTPRouteFilterList)
+ if err := r.client.List(ctx, httpFilterList); err != nil {
+ return nil, fmt.Errorf("failed to list HTTPRouteFilters: %w", err)
+ }
+
+ return httpFilterList.Items, nil
+}
+
+// processRouteFilterConfigMapRef adds the referenced ConfigMap in a HTTPRouteFilter
+// to the resourceTree
+func (r *gatewayAPIReconciler) processRouteFilterConfigMapRef(
+ ctx context.Context, filter *egv1a1.HTTPRouteFilter,
+ resourceMap *resourceMappings, resourceTree *resource.Resources,
+) {
+ if filter.Spec.DirectResponse != nil &&
+ filter.Spec.DirectResponse.Body != nil &&
+ filter.Spec.DirectResponse.Body.ValueRef != nil &&
+ string(filter.Spec.DirectResponse.Body.ValueRef.Kind) == resource.KindConfigMap {
+ configMap := new(corev1.ConfigMap)
+ err := r.client.Get(ctx,
+ types.NamespacedName{Namespace: filter.Namespace, Name: string(filter.Spec.DirectResponse.Body.ValueRef.Name)},
+ configMap)
+ // we don't return an error here, because we want to continue
+ // reconciling the rest of the HTTPRouteFilter despite that this
+ // reference is invalid.
+ // This HTTPRouteFilter will be marked as invalid in its status
+ // when translating to IR because the referenced configmap can't be
+ // found.
+ if err != nil {
+ r.log.Error(err,
+ "failed to process DirectResponse ValueRef for HTTPRouteFilter",
+ "filter", filter, "ValueRef", filter.Spec.DirectResponse.Body.ValueRef.Name)
+ }
+
+ resourceMap.allAssociatedNamespaces.Insert(filter.Namespace)
+ if !resourceMap.allAssociatedConfigMaps.Has(utils.NamespacedName(configMap).String()) {
+ resourceMap.allAssociatedConfigMaps.Insert(utils.NamespacedName(configMap).String())
+ resourceTree.ConfigMaps = append(resourceTree.ConfigMaps, configMap)
+ r.log.Info("processing ConfigMap", "namespace", filter.Namespace, "name", string(filter.Spec.DirectResponse.Body.ValueRef.Name))
+ }
+ }
+}
diff --git a/internal/provider/kubernetes/helpers.go b/internal/provider/kubernetes/helpers.go
index 847bdc35261..0069aba5c3c 100644
--- a/internal/provider/kubernetes/helpers.go
+++ b/internal/provider/kubernetes/helpers.go
@@ -18,6 +18,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
)
const (
@@ -141,7 +142,7 @@ func terminatesTLS(listener *gwapiv1.Listener) bool {
// refsSecret returns true if ref refers to a Secret.
func refsSecret(ref *gwapiv1.SecretObjectReference) bool {
return (ref.Group == nil || *ref.Group == corev1.GroupName) &&
- (ref.Kind == nil || *ref.Kind == gatewayapi.KindSecret)
+ (ref.Kind == nil || *ref.Kind == resource.KindSecret)
}
// validateBackendRef validates that ref is a reference to a local Service.
@@ -155,9 +156,9 @@ func validateBackendRef(ref *gwapiv1.BackendRef) error {
return nil
case gatewayapi.GroupDerefOr(ref.Group, corev1.GroupName) != corev1.GroupName && gatewayapi.GroupDerefOr(ref.Group, corev1.GroupName) != mcsapiv1a1.GroupName && gatewayapi.GroupDerefOr(ref.Group, corev1.GroupName) != egv1a1.GroupName:
return fmt.Errorf("invalid group; must be nil, empty string %q or %q", mcsapiv1a1.GroupName, egv1a1.GroupName)
- case gatewayapi.KindDerefOr(ref.Kind, gatewayapi.KindService) != gatewayapi.KindService && gatewayapi.KindDerefOr(ref.Kind, gatewayapi.KindService) != gatewayapi.KindServiceImport && gatewayapi.KindDerefOr(ref.Kind, gatewayapi.KindService) != egv1a1.KindBackend:
+ case gatewayapi.KindDerefOr(ref.Kind, resource.KindService) != resource.KindService && gatewayapi.KindDerefOr(ref.Kind, resource.KindService) != resource.KindServiceImport && gatewayapi.KindDerefOr(ref.Kind, resource.KindService) != egv1a1.KindBackend:
return fmt.Errorf("invalid kind %q; must be %q, %q or %q",
- *ref.BackendObjectReference.Kind, gatewayapi.KindService, gatewayapi.KindServiceImport, egv1a1.KindBackend)
+ *ref.BackendObjectReference.Kind, resource.KindService, resource.KindServiceImport, egv1a1.KindBackend)
}
return nil
diff --git a/internal/provider/kubernetes/helpers_test.go b/internal/provider/kubernetes/helpers_test.go
index 0d5deb0d5d3..38a634f9c7b 100644
--- a/internal/provider/kubernetes/helpers_test.go
+++ b/internal/provider/kubernetes/helpers_test.go
@@ -103,7 +103,6 @@ func TestGatewaysOfClass(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
gwList := &gwapiv1.GatewayList{Items: tc.gws}
actual := gatewaysOfClass(gc, gwList)
@@ -185,7 +184,6 @@ func TestIsGatewayClassAccepted(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
actual := isAccepted(tc.gc)
require.Equal(t, tc.expect, actual)
diff --git a/internal/provider/kubernetes/indexers.go b/internal/provider/kubernetes/indexers.go
index 443c667e349..7626ea32d52 100644
--- a/internal/provider/kubernetes/indexers.go
+++ b/internal/provider/kubernetes/indexers.go
@@ -19,6 +19,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
)
const (
@@ -39,25 +40,33 @@ const (
backendSecurityPolicyIndex = "backendSecurityPolicyIndex"
configMapCtpIndex = "configMapCtpIndex"
secretCtpIndex = "secretCtpIndex"
+ secretBtlsIndex = "secretBtlsIndex"
configMapBtlsIndex = "configMapBtlsIndex"
backendEnvoyExtensionPolicyIndex = "backendEnvoyExtensionPolicyIndex"
backendEnvoyProxyTelemetryIndex = "backendEnvoyProxyTelemetryIndex"
secretEnvoyProxyIndex = "secretEnvoyProxyIndex"
secretEnvoyExtensionPolicyIndex = "secretEnvoyExtensionPolicyIndex"
+ httpRouteFilterHTTPRouteIndex = "httpRouteFilterHTTPRouteIndex"
+ configMapBtpIndex = "configMapBtpIndex"
+ configMapHTTPRouteFilterIndex = "configMapHTTPRouteFilterIndex"
)
func addReferenceGrantIndexers(ctx context.Context, mgr manager.Manager) error {
- if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1b1.ReferenceGrant{}, targetRefGrantRouteIndex, func(rawObj client.Object) []string {
+ if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1b1.ReferenceGrant{}, targetRefGrantRouteIndex, getReferenceGrantIndexerFunc()); err != nil {
+ return err
+ }
+ return nil
+}
+
+func getReferenceGrantIndexerFunc() func(rawObj client.Object) []string {
+ return func(rawObj client.Object) []string {
refGrant := rawObj.(*gwapiv1b1.ReferenceGrant)
var referredServices []string
for _, target := range refGrant.Spec.To {
referredServices = append(referredServices, string(target.Kind))
}
return referredServices
- }); err != nil {
- return err
}
- return nil
}
// addHTTPRouteIndexers adds indexing on HTTPRoute.
@@ -72,6 +81,10 @@ func addHTTPRouteIndexers(ctx context.Context, mgr manager.Manager) error {
return err
}
+ if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1.HTTPRoute{}, httpRouteFilterHTTPRouteIndex, httpRouteFilterHTTPRouteIndexFunc); err != nil {
+ return err
+ }
+
return nil
}
@@ -79,7 +92,7 @@ func gatewayHTTPRouteIndexFunc(rawObj client.Object) []string {
httproute := rawObj.(*gwapiv1.HTTPRoute)
var gateways []string
for _, parent := range httproute.Spec.ParentRefs {
- if parent.Kind == nil || string(*parent.Kind) == gatewayapi.KindGateway {
+ if parent.Kind == nil || string(*parent.Kind) == resource.KindGateway {
// If an explicit Gateway namespace is not provided, use the HTTPRoute namespace to
// lookup the provided Gateway Name.
gateways = append(gateways,
@@ -98,9 +111,7 @@ func backendHTTPRouteIndexFunc(rawObj client.Object) []string {
var backendRefs []string
for _, rule := range httproute.Spec.Rules {
for _, backend := range rule.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService || string(*backend.Kind) == egv1a1.KindBackend {
- // If an explicit Backend namespace is not provided, use the HTTPRoute namespace to
- // lookup the provided Gateway Name.
+ if backend.Kind == nil || string(*backend.Kind) == resource.KindService || string(*backend.Kind) == egv1a1.KindBackend {
backendRefs = append(backendRefs,
types.NamespacedName{
Namespace: gatewayapi.NamespaceDerefOr(backend.Namespace, httproute.Namespace),
@@ -113,12 +124,32 @@ func backendHTTPRouteIndexFunc(rawObj client.Object) []string {
return backendRefs
}
+func httpRouteFilterHTTPRouteIndexFunc(rawObj client.Object) []string {
+ httproute := rawObj.(*gwapiv1.HTTPRoute)
+ var httpRouteFilterRefs []string
+ for _, rule := range httproute.Spec.Rules {
+ for _, filter := range rule.Filters {
+ if filter.ExtensionRef != nil && string(filter.ExtensionRef.Kind) == resource.KindHTTPRouteFilter {
+ // If an explicit Backend namespace is not provided, use the HTTPRoute namespace to
+ // lookup the provided Gateway Name.
+ httpRouteFilterRefs = append(httpRouteFilterRefs,
+ types.NamespacedName{
+ Namespace: httproute.Namespace,
+ Name: string(filter.ExtensionRef.Name),
+ }.String(),
+ )
+ }
+ }
+ }
+ return httpRouteFilterRefs
+}
+
func secretEnvoyProxyIndexFunc(rawObj client.Object) []string {
ep := rawObj.(*egv1a1.EnvoyProxy)
var secretReferences []string
if ep.Spec.BackendTLS != nil {
if ep.Spec.BackendTLS.ClientCertificateRef != nil {
- if *ep.Spec.BackendTLS.ClientCertificateRef.Kind == gatewayapi.KindSecret {
+ if *ep.Spec.BackendTLS.ClientCertificateRef.Kind == resource.KindSecret {
secretReferences = append(secretReferences,
types.NamespacedName{
Namespace: gatewayapi.NamespaceDerefOr(ep.Spec.BackendTLS.ClientCertificateRef.Namespace, ep.Namespace),
@@ -172,7 +203,7 @@ func accessLogRefs(ep *egv1a1.EnvoyProxy) []string {
}
for _, ref := range backendRefs {
- if ref.Kind == nil || string(*ref.Kind) == gatewayapi.KindService {
+ if ref.Kind == nil || string(*ref.Kind) == resource.KindService {
refs = append(refs,
types.NamespacedName{
Namespace: gatewayapi.NamespaceDerefOr(ref.Namespace, ep.Namespace),
@@ -197,7 +228,7 @@ func metricRefs(ep *egv1a1.EnvoyProxy) []string {
for _, sink := range ep.Spec.Telemetry.Metrics.Sinks {
if sink.OpenTelemetry != nil {
for _, backend := range sink.OpenTelemetry.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService {
+ if backend.Kind == nil || string(*backend.Kind) == resource.KindService {
refs = append(refs,
types.NamespacedName{
Namespace: gatewayapi.NamespaceDerefOr(backend.Namespace, ep.Namespace),
@@ -220,7 +251,7 @@ func traceRefs(ep *egv1a1.EnvoyProxy) []string {
}
for _, ref := range ep.Spec.Telemetry.Tracing.Provider.BackendRefs {
- if ref.Kind == nil || string(*ref.Kind) == gatewayapi.KindService {
+ if ref.Kind == nil || string(*ref.Kind) == resource.KindService {
refs = append(refs,
types.NamespacedName{
Namespace: gatewayapi.NamespaceDerefOr(ref.Namespace, ep.Namespace),
@@ -252,7 +283,7 @@ func gatewayGRPCRouteIndexFunc(rawObj client.Object) []string {
grpcroute := rawObj.(*gwapiv1.GRPCRoute)
var gateways []string
for _, parent := range grpcroute.Spec.ParentRefs {
- if parent.Kind == nil || string(*parent.Kind) == gatewayapi.KindGateway {
+ if parent.Kind == nil || string(*parent.Kind) == resource.KindGateway {
// If an explicit Gateway namespace is not provided, use the GRPCRoute namespace to
// lookup the provided Gateway Name.
gateways = append(gateways,
@@ -271,7 +302,7 @@ func backendGRPCRouteIndexFunc(rawObj client.Object) []string {
var backendRefs []string
for _, rule := range grpcroute.Spec.Rules {
for _, backend := range rule.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService || string(*backend.Kind) == egv1a1.KindBackend {
+ if backend.Kind == nil || string(*backend.Kind) == resource.KindService || string(*backend.Kind) == egv1a1.KindBackend {
// If an explicit Backend namespace is not provided, use the GRPCRoute namespace to
// lookup the provided Gateway Name.
backendRefs = append(backendRefs,
@@ -294,7 +325,7 @@ func addTLSRouteIndexers(ctx context.Context, mgr manager.Manager) error {
tlsRoute := rawObj.(*gwapiv1a2.TLSRoute)
var gateways []string
for _, parent := range tlsRoute.Spec.ParentRefs {
- if string(*parent.Kind) == gatewayapi.KindGateway {
+ if string(*parent.Kind) == resource.KindGateway {
// If an explicit Gateway namespace is not provided, use the TLSRoute namespace to
// lookup the provided Gateway Name.
gateways = append(gateways,
@@ -321,7 +352,7 @@ func backendTLSRouteIndexFunc(rawObj client.Object) []string {
var backendRefs []string
for _, rule := range tlsroute.Spec.Rules {
for _, backend := range rule.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService || string(*backend.Kind) == egv1a1.KindBackend {
+ if backend.Kind == nil || string(*backend.Kind) == resource.KindService || string(*backend.Kind) == egv1a1.KindBackend {
// If an explicit Backend namespace is not provided, use the TLSRoute namespace to
// lookup the provided Gateway Name.
backendRefs = append(backendRefs,
@@ -344,7 +375,7 @@ func addTCPRouteIndexers(ctx context.Context, mgr manager.Manager) error {
tcpRoute := rawObj.(*gwapiv1a2.TCPRoute)
var gateways []string
for _, parent := range tcpRoute.Spec.ParentRefs {
- if string(*parent.Kind) == gatewayapi.KindGateway {
+ if string(*parent.Kind) == resource.KindGateway {
// If an explicit Gateway namespace is not provided, use the TCPRoute namespace to
// lookup the provided Gateway Name.
gateways = append(gateways,
@@ -371,7 +402,7 @@ func backendTCPRouteIndexFunc(rawObj client.Object) []string {
var backendRefs []string
for _, rule := range tcpRoute.Spec.Rules {
for _, backend := range rule.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService || string(*backend.Kind) == egv1a1.KindBackend {
+ if backend.Kind == nil || string(*backend.Kind) == resource.KindService || string(*backend.Kind) == egv1a1.KindBackend {
// If an explicit Backend namespace is not provided, use the TCPRoute namespace to
// lookup the provided Gateway Name.
backendRefs = append(backendRefs,
@@ -396,7 +427,7 @@ func addUDPRouteIndexers(ctx context.Context, mgr manager.Manager) error {
udpRoute := rawObj.(*gwapiv1a2.UDPRoute)
var gateways []string
for _, parent := range udpRoute.Spec.ParentRefs {
- if string(*parent.Kind) == gatewayapi.KindGateway {
+ if string(*parent.Kind) == resource.KindGateway {
// If an explicit Gateway namespace is not provided, use the UDPRoute namespace to
// lookup the provided Gateway Name.
gateways = append(gateways,
@@ -423,7 +454,7 @@ func backendUDPRouteIndexFunc(rawObj client.Object) []string {
var backendRefs []string
for _, rule := range udproute.Spec.Rules {
for _, backend := range rule.BackendRefs {
- if backend.Kind == nil || string(*backend.Kind) == gatewayapi.KindService || string(*backend.Kind) == egv1a1.KindBackend {
+ if backend.Kind == nil || string(*backend.Kind) == resource.KindService || string(*backend.Kind) == egv1a1.KindBackend {
// If an explicit Backend namespace is not provided, use the UDPRoute namespace to
// lookup the provided Gateway Name.
backendRefs = append(backendRefs,
@@ -463,7 +494,7 @@ func secretGatewayIndexFunc(rawObj client.Object) []string {
continue
}
for _, cert := range listener.TLS.CertificateRefs {
- if *cert.Kind == gatewayapi.KindSecret {
+ if *cert.Kind == resource.KindSecret {
// If an explicit Secret namespace is not provided, use the Gateway namespace to
// lookup the provided Secret Name.
secretReferences = append(secretReferences,
@@ -507,7 +538,7 @@ func secretSecurityPolicyIndexFunc(rawObj client.Object) []string {
securityPolicy := rawObj.(*egv1a1.SecurityPolicy)
var (
- secretReferences []gwapiv1b1.SecretObjectReference
+ secretReferences []gwapiv1.SecretObjectReference
values []string
)
@@ -582,7 +613,7 @@ func configMapCtpIndexFunc(rawObj client.Object) []string {
var configMapReferences []string
if ctp.Spec.TLS != nil && ctp.Spec.TLS.ClientValidation != nil {
for _, caCertRef := range ctp.Spec.TLS.ClientValidation.CACertificateRefs {
- if caCertRef.Kind != nil && string(*caCertRef.Kind) == gatewayapi.KindConfigMap {
+ if caCertRef.Kind != nil && string(*caCertRef.Kind) == resource.KindConfigMap {
// If an explicit configmap namespace is not provided, use the ctp namespace to
// lookup the provided config map Name.
configMapReferences = append(configMapReferences,
@@ -602,7 +633,7 @@ func secretCtpIndexFunc(rawObj client.Object) []string {
var secretReferences []string
if ctp.Spec.TLS != nil && ctp.Spec.TLS.ClientValidation != nil {
for _, caCertRef := range ctp.Spec.TLS.ClientValidation.CACertificateRefs {
- if caCertRef.Kind == nil || (string(*caCertRef.Kind) == gatewayapi.KindSecret) {
+ if caCertRef.Kind == nil || (string(*caCertRef.Kind) == resource.KindSecret) {
// If an explicit namespace is not provided, use the ctp namespace to
// lookup the provided secrent Name.
secretReferences = append(secretReferences,
@@ -617,7 +648,66 @@ func secretCtpIndexFunc(rawObj client.Object) []string {
return secretReferences
}
-// addBtlsIndexers adds indexing on BackendTLSPolicy, for ConfigMap objects that are
+// addBtpIndexers adds indexing on BackendTrafficPolicy, for ConfigMap objects that are
+// referenced in BackendTrafficPolicy objects. This helps in querying for BackendTrafficPolies that are
+// affected by a particular ConfigMap CRUD.
+func addBtpIndexers(ctx context.Context, mgr manager.Manager) error {
+ if err := mgr.GetFieldIndexer().IndexField(ctx, &egv1a1.BackendTrafficPolicy{}, configMapBtpIndex, configMapBtpIndexFunc); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func configMapBtpIndexFunc(rawObj client.Object) []string {
+ btp := rawObj.(*egv1a1.BackendTrafficPolicy)
+ var configMapReferences []string
+
+ for _, ro := range btp.Spec.ResponseOverride {
+ if ro.Response.Body.ValueRef != nil {
+ if string(ro.Response.Body.ValueRef.Kind) == resource.KindConfigMap {
+ configMapReferences = append(configMapReferences,
+ types.NamespacedName{
+ Namespace: btp.Namespace,
+ Name: string(ro.Response.Body.ValueRef.Name),
+ }.String(),
+ )
+ }
+ }
+ }
+ return configMapReferences
+}
+
+// addRouteFilterIndexers adds indexing on HTTPRouteFilter, for ConfigMap objects that are
+// referenced in HTTPRouteFilter objects. This helps in querying for HTTPRouteFilters that are
+// affected by a particular ConfigMap CRUD.
+func addRouteFilterIndexers(ctx context.Context, mgr manager.Manager) error {
+ if err := mgr.GetFieldIndexer().IndexField(ctx, &egv1a1.HTTPRouteFilter{},
+ configMapHTTPRouteFilterIndex, configMapRouteFilterIndexFunc); err != nil {
+ return err
+ }
+ return nil
+}
+
+func configMapRouteFilterIndexFunc(rawObj client.Object) []string {
+ filter := rawObj.(*egv1a1.HTTPRouteFilter)
+ var configMapReferences []string
+ if filter.Spec.DirectResponse != nil &&
+ filter.Spec.DirectResponse.Body != nil &&
+ filter.Spec.DirectResponse.Body.ValueRef != nil {
+ if string(filter.Spec.DirectResponse.Body.ValueRef.Kind) == resource.KindConfigMap {
+ configMapReferences = append(configMapReferences,
+ types.NamespacedName{
+ Namespace: filter.Namespace,
+ Name: string(filter.Spec.DirectResponse.Body.ValueRef.Name),
+ }.String(),
+ )
+ }
+ }
+ return configMapReferences
+}
+
+// addBtlsIndexers adds indexing on BackendTLSPolicy, for ConfigMap and Secret objects that are
// referenced in BackendTLSPolicy objects. This helps in querying for BackendTLSPolicies that are
// affected by a particular ConfigMap CRUD.
func addBtlsIndexers(ctx context.Context, mgr manager.Manager) error {
@@ -625,6 +715,9 @@ func addBtlsIndexers(ctx context.Context, mgr manager.Manager) error {
return err
}
+ if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1a3.BackendTLSPolicy{}, secretBtlsIndex, secretBtlsIndexFunc); err != nil {
+ return err
+ }
return nil
}
@@ -633,7 +726,7 @@ func configMapBtlsIndexFunc(rawObj client.Object) []string {
var configMapReferences []string
if btls.Spec.Validation.CACertificateRefs != nil {
for _, caCertRef := range btls.Spec.Validation.CACertificateRefs {
- if string(caCertRef.Kind) == gatewayapi.KindConfigMap {
+ if string(caCertRef.Kind) == resource.KindConfigMap {
configMapReferences = append(configMapReferences,
types.NamespacedName{
Namespace: btls.Namespace,
@@ -646,6 +739,24 @@ func configMapBtlsIndexFunc(rawObj client.Object) []string {
return configMapReferences
}
+func secretBtlsIndexFunc(rawObj client.Object) []string {
+ btls := rawObj.(*gwapiv1a3.BackendTLSPolicy)
+ var secretReferences []string
+ if btls.Spec.Validation.CACertificateRefs != nil {
+ for _, caCertRef := range btls.Spec.Validation.CACertificateRefs {
+ if string(caCertRef.Kind) == resource.KindSecret {
+ secretReferences = append(secretReferences,
+ types.NamespacedName{
+ Namespace: btls.Namespace,
+ Name: string(caCertRef.Name),
+ }.String(),
+ )
+ }
+ }
+ }
+ return secretReferences
+}
+
// addEnvoyExtensionPolicyIndexers adds indexing on EnvoyExtensionPolicy.
// - For Service objects that are referenced in EnvoyExtensionPolicy objects via
// `.spec.extProc.[*].service.backendObjectReference`. This helps in querying for
diff --git a/internal/provider/kubernetes/kubernetes.go b/internal/provider/kubernetes/kubernetes.go
index df1c0d534b2..56f96e70a18 100644
--- a/internal/provider/kubernetes/kubernetes.go
+++ b/internal/provider/kubernetes/kubernetes.go
@@ -11,14 +11,17 @@ import (
"time"
"k8s.io/client-go/rest"
+ "k8s.io/klog/v2"
"k8s.io/utils/ptr"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/config"
"sigs.k8s.io/controller-runtime/pkg/healthz"
+ "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway"
ec "github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/message"
@@ -33,37 +36,40 @@ type Provider struct {
}
// New creates a new Provider from the provided EnvoyGateway.
-func New(cfg *rest.Config, svr *ec.Server, resources *message.ProviderResources) (*Provider, error) {
+func New(restCfg *rest.Config, svrCfg *ec.Server, resources *message.ProviderResources) (*Provider, error) {
// TODO: Decide which mgr opts should be exposed through envoygateway.provider.kubernetes API.
mgrOpts := manager.Options{
Scheme: envoygateway.GetScheme(),
- Logger: svr.Logger.Logger,
+ Logger: svrCfg.Logger.Logger,
HealthProbeBindAddress: ":8081",
LeaderElectionID: "5b9825d2.gateway.envoyproxy.io",
- LeaderElectionNamespace: svr.Namespace,
+ LeaderElectionNamespace: svrCfg.Namespace,
}
- if !ptr.Deref(svr.EnvoyGateway.Provider.Kubernetes.LeaderElection.Disable, false) {
+ log.SetLogger(mgrOpts.Logger)
+ klog.SetLogger(mgrOpts.Logger)
+
+ if !ptr.Deref(svrCfg.EnvoyGateway.Provider.Kubernetes.LeaderElection.Disable, false) {
mgrOpts.LeaderElection = true
- if svr.EnvoyGateway.Provider.Kubernetes.LeaderElection.LeaseDuration != nil {
- ld, err := time.ParseDuration(string(*svr.EnvoyGateway.Provider.Kubernetes.LeaderElection.LeaseDuration))
+ if svrCfg.EnvoyGateway.Provider.Kubernetes.LeaderElection.LeaseDuration != nil {
+ ld, err := time.ParseDuration(string(*svrCfg.EnvoyGateway.Provider.Kubernetes.LeaderElection.LeaseDuration))
if err != nil {
return nil, err
}
mgrOpts.LeaseDuration = ptr.To(ld)
}
- if svr.EnvoyGateway.Provider.Kubernetes.LeaderElection.RetryPeriod != nil {
- rp, err := time.ParseDuration(string(*svr.EnvoyGateway.Provider.Kubernetes.LeaderElection.RetryPeriod))
+ if svrCfg.EnvoyGateway.Provider.Kubernetes.LeaderElection.RetryPeriod != nil {
+ rp, err := time.ParseDuration(string(*svrCfg.EnvoyGateway.Provider.Kubernetes.LeaderElection.RetryPeriod))
if err != nil {
return nil, err
}
mgrOpts.RetryPeriod = ptr.To(rp)
}
- if svr.EnvoyGateway.Provider.Kubernetes.LeaderElection.RenewDeadline != nil {
- rd, err := time.ParseDuration(string(*svr.EnvoyGateway.Provider.Kubernetes.LeaderElection.RenewDeadline))
+ if svrCfg.EnvoyGateway.Provider.Kubernetes.LeaderElection.RenewDeadline != nil {
+ rd, err := time.ParseDuration(string(*svrCfg.EnvoyGateway.Provider.Kubernetes.LeaderElection.RenewDeadline))
if err != nil {
return nil, err
}
@@ -72,13 +78,13 @@ func New(cfg *rest.Config, svr *ec.Server, resources *message.ProviderResources)
mgrOpts.Controller = config.Controller{NeedLeaderElection: ptr.To(false)}
}
- if svr.EnvoyGateway.NamespaceMode() {
+ if svrCfg.EnvoyGateway.NamespaceMode() {
mgrOpts.Cache.DefaultNamespaces = make(map[string]cache.Config)
- for _, watchNS := range svr.EnvoyGateway.Provider.Kubernetes.Watch.Namespaces {
+ for _, watchNS := range svrCfg.EnvoyGateway.Provider.Kubernetes.Watch.Namespaces {
mgrOpts.Cache.DefaultNamespaces[watchNS] = cache.Config{}
}
}
- mgr, err := ctrl.NewManager(cfg, mgrOpts)
+ mgr, err := ctrl.NewManager(restCfg, mgrOpts)
if err != nil {
return nil, fmt.Errorf("failed to create manager: %w", err)
}
@@ -89,7 +95,7 @@ func New(cfg *rest.Config, svr *ec.Server, resources *message.ProviderResources)
}
// Create and register the controllers with the manager.
- if err := newGatewayAPIController(mgr, svr, updateHandler.Writer(), resources); err != nil {
+ if err := newGatewayAPIController(mgr, svrCfg, updateHandler.Writer(), resources); err != nil {
return nil, fmt.Errorf("failted to create gatewayapi controller: %w", err)
}
@@ -103,10 +109,10 @@ func New(cfg *rest.Config, svr *ec.Server, resources *message.ProviderResources)
return nil, fmt.Errorf("unable to set up ready check: %w", err)
}
- // Emit elected & continue with deployment of infra resources
+ // Emit elected & continue with the tasks that require leadership.
go func() {
<-mgr.Elected()
- close(svr.Elected)
+ svrCfg.Elected.Done()
}()
return &Provider{
@@ -115,6 +121,10 @@ func New(cfg *rest.Config, svr *ec.Server, resources *message.ProviderResources)
}, nil
}
+func (p *Provider) Type() egv1a1.ProviderType {
+ return egv1a1.ProviderTypeKubernetes
+}
+
// Start starts the Provider synchronously until a message is received from ctx.
func (p *Provider) Start(ctx context.Context) error {
errChan := make(chan error)
diff --git a/internal/provider/kubernetes/kubernetes_test.go b/internal/provider/kubernetes/kubernetes_test.go
index da58fcd4188..135de799948 100644
--- a/internal/provider/kubernetes/kubernetes_test.go
+++ b/internal/provider/kubernetes/kubernetes_test.go
@@ -1,5 +1,4 @@
//go:build integration
-// +build integration
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
@@ -35,6 +34,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/message"
"github.com/envoyproxy/gateway/internal/provider/kubernetes/test"
"github.com/envoyproxy/gateway/internal/utils"
@@ -45,6 +45,15 @@ const (
defaultTick = time.Millisecond * 20
)
+func TestMain(m *testing.M) {
+ // related to https://github.com/kubernetes-sigs/controller-runtime/pull/2902
+ // this is a workaround to skip the name validation for the test
+ skipNameValidation = func() *bool {
+ return ptr.To(true)
+ }
+ os.Exit(m.Run())
+}
+
func TestProvider(t *testing.T) {
// Setup the test environment.
testEnv, cliCfg, err := startEnv()
@@ -1420,26 +1429,20 @@ func TestNamespaceSelectorProvider(t *testing.T) {
require.NoError(t, cli.Delete(ctx, nonWatchedSvc))
}()
- watchedHTTPRoute := test.GetHTTPRoute(
- types.NamespacedName{
- Namespace: watchedNS.Name,
- Name: "watched-http-route",
- },
- watchedGateway.Name,
- types.NamespacedName{Name: watchedSvc.Name}, 80)
+ watchedHTTPRoute := test.GetHTTPRoute(types.NamespacedName{
+ Namespace: watchedNS.Name,
+ Name: "watched-http-route",
+ }, watchedGateway.Name, types.NamespacedName{Name: watchedSvc.Name}, 80, "")
require.NoError(t, cli.Create(ctx, watchedHTTPRoute))
defer func() {
require.NoError(t, cli.Delete(ctx, watchedHTTPRoute))
}()
- nonWatchedHTTPRoute := test.GetHTTPRoute(
- types.NamespacedName{
- Namespace: nonWatchedNS.Name,
- Name: "non-watched-http-route",
- },
- nonWatchedGateway.Name,
- types.NamespacedName{Name: nonWatchedSvc.Name}, 8001)
+ nonWatchedHTTPRoute := test.GetHTTPRoute(types.NamespacedName{
+ Namespace: nonWatchedNS.Name,
+ Name: "non-watched-http-route",
+ }, nonWatchedGateway.Name, types.NamespacedName{Name: nonWatchedSvc.Name}, 8001, "")
require.NoError(t, cli.Create(ctx, nonWatchedHTTPRoute))
defer func() {
require.NoError(t, cli.Delete(ctx, nonWatchedHTTPRoute))
@@ -1591,7 +1594,7 @@ func TestNamespaceSelectorProvider(t *testing.T) {
}, defaultWait, defaultTick)
}
-func waitUntilGatewayClassResourcesAreReady(resources *message.ProviderResources, gatewayClassName string) (*gatewayapi.Resources, bool) {
+func waitUntilGatewayClassResourcesAreReady(resources *message.ProviderResources, gatewayClassName string) (*resource.Resources, bool) {
res := resources.GetResourcesByGatewayClass(gatewayClassName)
if res == nil {
return nil, false
diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go
index e64c08619db..16bb9361b04 100644
--- a/internal/provider/kubernetes/predicates.go
+++ b/internal/provider/kubernetes/predicates.go
@@ -13,6 +13,7 @@ import (
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
@@ -103,7 +104,7 @@ func matchLabelsAndExpressions(ls *metav1.LabelSelector, objLabels map[string]st
}
// validateGatewayForReconcile returns true if the provided object is a Gateway
-// using a GatewayClass matching the configured gatewayclass controller name.
+// using a GatewayClass matching the configured GatewayClass controller name.
func (r *gatewayAPIReconciler) validateGatewayForReconcile(obj client.Object) bool {
gw, ok := obj.(*gwapiv1.Gateway)
if !ok {
@@ -114,14 +115,15 @@ func (r *gatewayAPIReconciler) validateGatewayForReconcile(obj client.Object) bo
gc := &gwapiv1.GatewayClass{}
key := types.NamespacedName{Name: string(gw.Spec.GatewayClassName)}
if err := r.client.Get(context.Background(), key, gc); err != nil {
- r.log.Error(err, "failed to get gatewayclass", "name", gw.Spec.GatewayClassName)
+ r.log.Error(err, "failed to get GatewayClass", "name", gw.Spec.GatewayClassName)
return false
}
if gc.Spec.ControllerName != r.classController {
- r.log.Info("gatewayclass controller name", string(gc.Spec.ControllerName), "class controller name", string(r.classController))
- r.log.Info("gatewayclass name for gateway doesn't match configured name",
- "namespace", gw.Namespace, "name", gw.Name)
+ r.log.Info("GatewayClass name for gateway doesn't match configured name",
+ "namespace", gw.Namespace, "name", gw.Name,
+ "GatewayClass controller name", string(gc.Spec.ControllerName),
+ "class controller name", string(r.classController))
return false
}
@@ -142,23 +144,53 @@ func (r *gatewayAPIReconciler) validateSecretForReconcile(obj client.Object) boo
return true
}
- if r.isSecurityPolicyReferencingSecret(&nsName) {
- return true
+ if r.spCRDExists {
+ if r.isSecurityPolicyReferencingSecret(&nsName) {
+ return true
+ }
}
- if r.isCtpReferencingSecret(&nsName) {
- return true
+ if r.ctpCRDExists {
+ if r.isCtpReferencingSecret(&nsName) {
+ return true
+ }
}
if r.isOIDCHMACSecret(&nsName) {
return true
}
- if r.isEnvoyProxyReferencingSecret(&nsName) {
- return true
+ if r.epCRDExists {
+ if r.isEnvoyProxyReferencingSecret(&nsName) {
+ return true
+ }
+ }
+
+ if r.eepCRDExists {
+ if r.isExtensionPolicyReferencingSecret(&nsName) {
+ return true
+ }
+ }
+
+ if r.bTLSPolicyCRDExists {
+ if r.isBackendTLSPolicyReferencingSecret(&nsName) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (r *gatewayAPIReconciler) isBackendTLSPolicyReferencingSecret(nsName *types.NamespacedName) bool {
+ btlsList := &gwapiv1a3.BackendTLSPolicyList{}
+ if err := r.client.List(context.Background(), btlsList, &client.ListOptions{
+ FieldSelector: fields.OneTermEqualSelector(secretBtlsIndex, nsName.String()),
+ }); err != nil {
+ r.log.Error(err, "unable to find associated BackendTLSPolicy")
+ return false
}
- if r.isExtensionPolicyReferencingSecret(&nsName) {
+ if len(btlsList.Items) > 0 {
return true
}
@@ -208,7 +240,6 @@ func (r *gatewayAPIReconciler) isGatewayReferencingSecret(nsName *types.Namespac
}
for _, gw := range gwList.Items {
- gw := gw
if !r.validateGatewayForReconcile(&gw) {
return false
}
@@ -263,7 +294,7 @@ func (r *gatewayAPIReconciler) validateServiceForReconcile(obj client.Object) bo
// Check if the Service belongs to a Gateway, if so, update the Gateway status.
gtw := r.findOwningGateway(ctx, labels)
if gtw != nil {
- r.updateStatusForGateway(ctx, gtw)
+ r.updateGatewayStatus(gtw)
return false
}
@@ -282,15 +313,25 @@ func (r *gatewayAPIReconciler) validateServiceForReconcile(obj client.Object) bo
return true
}
- if r.isSecurityPolicyReferencingBackend(&nsName) {
- return true
+ if r.spCRDExists {
+ if r.isSecurityPolicyReferencingBackend(&nsName) {
+ return true
+ }
}
- if r.isEnvoyProxyReferencingBackend(&nsName) {
- return true
+ if r.epCRDExists {
+ if r.isEnvoyProxyReferencingBackend(&nsName) {
+ return true
+ }
+ }
+
+ if r.eepCRDExists {
+ if r.isEnvoyExtensionPolicyReferencingBackend(&nsName) {
+ return true
+ }
}
- return r.isEnvoyExtensionPolicyReferencingBackend(&nsName)
+ return false
}
// validateBackendForReconcile tries finding the owning Gateway of the Backend
@@ -308,15 +349,25 @@ func (r *gatewayAPIReconciler) validateBackendForReconcile(obj client.Object) bo
return true
}
- if r.isSecurityPolicyReferencingBackend(&nsName) {
- return true
+ if r.spCRDExists {
+ if r.isSecurityPolicyReferencingBackend(&nsName) {
+ return true
+ }
}
- if r.isEnvoyProxyReferencingBackend(&nsName) {
- return true
+ if r.epCRDExists {
+ if r.isEnvoyProxyReferencingBackend(&nsName) {
+ return true
+ }
+ }
+
+ if r.eepCRDExists {
+ if r.isEnvoyExtensionPolicyReferencingBackend(&nsName) {
+ return true
+ }
}
- return r.isEnvoyExtensionPolicyReferencingBackend(&nsName)
+ return false
}
func (r *gatewayAPIReconciler) isSecurityPolicyReferencingBackend(nsName *types.NamespacedName) bool {
@@ -352,51 +403,67 @@ func (r *gatewayAPIReconciler) isRouteReferencingBackend(nsName *types.Namespace
httpRouteList := &gwapiv1.HTTPRouteList{}
if err := r.client.List(ctx, httpRouteList, &client.ListOptions{
FieldSelector: fields.OneTermEqualSelector(backendHTTPRouteIndex, nsName.String()),
- }); err != nil {
- r.log.Error(err, "unable to find associated HTTPRoutes")
+ }); err != nil && !kerrors.IsNotFound(err) {
+ r.log.Error(err, "failed to find associated HTTPRoutes")
return false
}
-
- grpcRouteList := &gwapiv1.GRPCRouteList{}
- if err := r.client.List(ctx, grpcRouteList, &client.ListOptions{
- FieldSelector: fields.OneTermEqualSelector(backendGRPCRouteIndex, nsName.String()),
- }); err != nil {
- r.log.Error(err, "unable to find associated GRPCRoutes")
- return false
+ if len(httpRouteList.Items) > 0 {
+ return true
}
- tlsRouteList := &gwapiv1a2.TLSRouteList{}
- if err := r.client.List(ctx, tlsRouteList, &client.ListOptions{
- FieldSelector: fields.OneTermEqualSelector(backendTLSRouteIndex, nsName.String()),
- }); err != nil {
- r.log.Error(err, "unable to find associated TLSRoutes")
- return false
+ if r.grpcRouteCRDExists {
+ grpcRouteList := &gwapiv1.GRPCRouteList{}
+ if err := r.client.List(ctx, grpcRouteList, &client.ListOptions{
+ FieldSelector: fields.OneTermEqualSelector(backendGRPCRouteIndex, nsName.String()),
+ }); err != nil && !kerrors.IsNotFound(err) {
+ r.log.Error(err, "failed to find associated GRPCRoutes")
+ return false
+ }
+ if len(grpcRouteList.Items) > 0 {
+ return true
+ }
}
- tcpRouteList := &gwapiv1a2.TCPRouteList{}
- if err := r.client.List(ctx, tcpRouteList, &client.ListOptions{
- FieldSelector: fields.OneTermEqualSelector(backendTCPRouteIndex, nsName.String()),
- }); err != nil {
- r.log.Error(err, "unable to find associated TCPRoutes")
- return false
+ if r.tlsRouteCRDExists {
+ tlsRouteList := &gwapiv1a2.TLSRouteList{}
+ if err := r.client.List(ctx, tlsRouteList, &client.ListOptions{
+ FieldSelector: fields.OneTermEqualSelector(backendTLSRouteIndex, nsName.String()),
+ }); err != nil && !kerrors.IsNotFound(err) {
+ r.log.Error(err, "failed to find associated TLSRoutes")
+ return false
+ }
+ if len(tlsRouteList.Items) > 0 {
+ return true
+ }
}
- udpRouteList := &gwapiv1a2.UDPRouteList{}
- if err := r.client.List(ctx, udpRouteList, &client.ListOptions{
- FieldSelector: fields.OneTermEqualSelector(backendUDPRouteIndex, nsName.String()),
- }); err != nil {
- r.log.Error(err, "unable to find associated UDPRoutes")
- return false
+ if r.tcpRouteCRDExists {
+ tcpRouteList := &gwapiv1a2.TCPRouteList{}
+ if err := r.client.List(ctx, tcpRouteList, &client.ListOptions{
+ FieldSelector: fields.OneTermEqualSelector(backendTCPRouteIndex, nsName.String()),
+ }); err != nil && !kerrors.IsNotFound(err) {
+ r.log.Error(err, "failed to find associated TCPRoutes")
+ return false
+ }
+ if len(tcpRouteList.Items) > 0 {
+ return true
+ }
}
- // Check how many Route objects refer this Backend
- allAssociatedRoutes := len(httpRouteList.Items) +
- len(grpcRouteList.Items) +
- len(tlsRouteList.Items) +
- len(tcpRouteList.Items) +
- len(udpRouteList.Items)
+ if r.udpRouteCRDExists {
+ udpRouteList := &gwapiv1a2.UDPRouteList{}
+ if err := r.client.List(ctx, udpRouteList, &client.ListOptions{
+ FieldSelector: fields.OneTermEqualSelector(backendUDPRouteIndex, nsName.String()),
+ }); err != nil && !kerrors.IsNotFound(err) {
+ r.log.Error(err, "failed to find associated UDPRoutes")
+ return false
+ }
+ if len(udpRouteList.Items) > 0 {
+ return true
+ }
+ }
- return allAssociatedRoutes != 0
+ return false
}
// validateEndpointSliceForReconcile returns true if the endpointSlice references
@@ -428,35 +495,40 @@ func (r *gatewayAPIReconciler) validateEndpointSliceForReconcile(obj client.Obje
return true
}
- if r.isSecurityPolicyReferencingBackend(&nsName) {
- return true
+ if r.spCRDExists {
+ if r.isSecurityPolicyReferencingBackend(&nsName) {
+ return true
+ }
}
- if r.isEnvoyProxyReferencingBackend(&nsName) {
- return true
+ if r.epCRDExists {
+ if r.isEnvoyProxyReferencingBackend(&nsName) {
+ return true
+ }
}
- return r.isEnvoyExtensionPolicyReferencingBackend(&nsName)
+ if r.eepCRDExists {
+ if r.isEnvoyExtensionPolicyReferencingBackend(&nsName) {
+ return true
+ }
+ }
+
+ return false
}
-// validateDeploymentForReconcile tries finding the owning Gateway of the Deployment
+// validateObjectForReconcile tries finding the owning Gateway of the Deployment or DaemonSet
// if it exists, finds the Gateway's Service, and further updates the Gateway
-// status Ready condition. No Deployments are pushed for reconciliation.
-func (r *gatewayAPIReconciler) validateDeploymentForReconcile(obj client.Object) bool {
+// status Ready condition. No Deployments or DaemonSets are pushed for reconciliation.
+func (r *gatewayAPIReconciler) validateObjectForReconcile(obj client.Object) bool {
ctx := context.Background()
- deployment, ok := obj.(*appsv1.Deployment)
- if !ok {
- r.log.Info("unexpected object type, bypassing reconciliation", "object", obj)
- return false
- }
- labels := deployment.GetLabels()
+ labels := obj.GetLabels()
- // Only deployments in the configured namespace should be reconciled.
- if deployment.Namespace == r.namespace {
- // Check if the deployment belongs to a Gateway, if so, update the Gateway status.
+ // Only objects in the configured namespace should be reconciled.
+ if obj.GetNamespace() == r.namespace {
+ // Check if the obj belongs to a Gateway, if so, update the Gateway status.
gtw := r.findOwningGateway(ctx, labels)
if gtw != nil {
- r.updateStatusForGateway(ctx, gtw)
+ r.updateGatewayStatus(gtw)
return false
}
}
@@ -471,27 +543,42 @@ func (r *gatewayAPIReconciler) validateDeploymentForReconcile(obj client.Object)
return false
}
- // There is no need to reconcile the Deployment any further.
+ // There is no need to reconcile the object any further.
return false
}
-// envoyDeploymentForGateway returns the Envoy Deployment, returning nil if the Deployment doesn't exist.
-func (r *gatewayAPIReconciler) envoyDeploymentForGateway(ctx context.Context, gateway *gwapiv1.Gateway) (*appsv1.Deployment, error) {
- var deployments appsv1.DeploymentList
- labelSelector := labels.SelectorFromSet(labels.Set(gatewayapi.OwnerLabels(gateway, r.mergeGateways.Has(string(gateway.Spec.GatewayClassName)))))
- if err := r.client.List(ctx, &deployments, &client.ListOptions{
- LabelSelector: labelSelector,
- Namespace: r.namespace,
- }); err != nil {
- if kerrors.IsNotFound(err) {
+// envoyObjectForGateway returns the Envoy Deployment or DaemonSet, returning nil if neither exists.
+func (r *gatewayAPIReconciler) envoyObjectForGateway(ctx context.Context, gateway *gwapiv1.Gateway) (client.Object, error) {
+ // Helper func to list and return the first object from results
+ listResource := func(list client.ObjectList) (client.Object, error) {
+ if err := r.client.List(ctx, list, &client.ListOptions{
+ LabelSelector: labels.SelectorFromSet(gatewayapi.OwnerLabels(gateway, r.mergeGateways.Has(string(gateway.Spec.GatewayClassName)))),
+ Namespace: r.namespace,
+ }); err != nil {
+ if !kerrors.IsNotFound(err) {
+ return nil, err
+ }
+ }
+ items, err := meta.ExtractList(list)
+ if err != nil || len(items) == 0 {
return nil, nil
}
- return nil, err
+ return items[0].(client.Object), nil
}
- if len(deployments.Items) == 0 {
- return nil, nil
+
+ // Check for Deployment
+ deployments := &appsv1.DeploymentList{}
+ if obj, err := listResource(deployments); obj != nil || err != nil {
+ return obj, err
+ }
+
+ // Check for DaemonSet
+ daemonsets := &appsv1.DaemonSetList{}
+ if obj, err := listResource(daemonsets); obj != nil || err != nil {
+ return obj, err
}
- return &deployments.Items[0], nil
+
+ return nil, nil
}
// envoyServiceForGateway returns the Envoy service, returning nil if the service doesn't exist.
@@ -549,13 +636,32 @@ func (r *gatewayAPIReconciler) updateStatusForGatewaysUnderGatewayClass(ctx cont
}
for _, gateway := range gateways.Items {
- gateway := gateway
- r.updateStatusForGateway(ctx, &gateway)
+ r.updateGatewayStatus(&gateway)
}
return nil
}
+// updateGatewayStatus triggers a status update for the Gateway.
+func (r *gatewayAPIReconciler) updateGatewayStatus(gateway *gwapiv1.Gateway) {
+ gwName := utils.NamespacedName(gateway)
+ status := &gateway.Status
+ // Use the existing status if it exists to avoid losing the status calculated by the Gateway API translator.
+ if existing, ok := r.resources.GatewayStatuses.Load(gwName); ok {
+ status = existing
+ }
+
+ // Since the status does not reflect the actual changed status, we need to delete it first
+ // to prevent it from being considered unchanged. This ensures that subscribers receive the update event.
+ r.resources.GatewayStatuses.Delete(gwName)
+ // The status that is stored in the GatewayStatuses GatewayStatuses is solely used to trigger the status updater
+ // and does not reflect the real changed status.
+ //
+ // The status updater will check the Envoy Proxy service to get the addresses of the Gateway,
+ // and check the Envoy Proxy Deployment/DaemonSet to get the status of the Gateway workload.
+ r.resources.GatewayStatuses.Store(gwName, status)
+}
+
func (r *gatewayAPIReconciler) handleNode(obj client.Object) bool {
ctx := context.Background()
node, ok := obj.(*corev1.Node)
@@ -578,7 +684,7 @@ func (r *gatewayAPIReconciler) handleNode(obj client.Object) bool {
return true
}
-// validateConfigMapForReconcile checks whether the ConfigMap belongs to a valid ClientTrafficPolicy.
+// validateConfigMapForReconcile checks whether the ConfigMap belongs to a valid EG resource.
func (r *gatewayAPIReconciler) validateConfigMapForReconcile(obj client.Object) bool {
configMap, ok := obj.(*corev1.ConfigMap)
if !ok {
@@ -586,31 +692,63 @@ func (r *gatewayAPIReconciler) validateConfigMapForReconcile(obj client.Object)
return false
}
- ctpList := &egv1a1.ClientTrafficPolicyList{}
- if err := r.client.List(context.Background(), ctpList, &client.ListOptions{
- FieldSelector: fields.OneTermEqualSelector(configMapCtpIndex, utils.NamespacedName(configMap).String()),
- }); err != nil {
- r.log.Error(err, "unable to find associated ClientTrafficPolicy")
- return false
+ if r.ctpCRDExists {
+ ctpList := &egv1a1.ClientTrafficPolicyList{}
+ if err := r.client.List(context.Background(), ctpList, &client.ListOptions{
+ FieldSelector: fields.OneTermEqualSelector(configMapCtpIndex, utils.NamespacedName(configMap).String()),
+ }); err != nil {
+ r.log.Error(err, "unable to find associated ClientTrafficPolicy")
+ return false
+ }
+
+ if len(ctpList.Items) > 0 {
+ return true
+ }
}
- if len(ctpList.Items) == 0 {
- return false
+ if r.bTLSPolicyCRDExists {
+ btlsList := &gwapiv1a3.BackendTLSPolicyList{}
+ if err := r.client.List(context.Background(), btlsList, &client.ListOptions{
+ FieldSelector: fields.OneTermEqualSelector(configMapBtlsIndex, utils.NamespacedName(configMap).String()),
+ }); err != nil {
+ r.log.Error(err, "unable to find associated BackendTLSPolicy")
+ return false
+ }
+
+ if len(btlsList.Items) > 0 {
+ return true
+ }
}
- btlsList := &gwapiv1a3.BackendTLSPolicyList{}
- if err := r.client.List(context.Background(), btlsList, &client.ListOptions{
- FieldSelector: fields.OneTermEqualSelector(configMapBtlsIndex, utils.NamespacedName(configMap).String()),
- }); err != nil {
- r.log.Error(err, "unable to find associated BackendTLSPolicy")
- return false
+ if r.btpCRDExists {
+ btpList := &egv1a1.BackendTrafficPolicyList{}
+ if err := r.client.List(context.Background(), btpList, &client.ListOptions{
+ FieldSelector: fields.OneTermEqualSelector(configMapBtpIndex, utils.NamespacedName(configMap).String()),
+ }); err != nil {
+ r.log.Error(err, "unable to find associated BackendTrafficPolicy")
+ return false
+ }
+
+ if len(btpList.Items) > 0 {
+ return true
+ }
}
- if len(btlsList.Items) == 0 {
- return false
+ if r.hrfCRDExists {
+ routeFilterList := &egv1a1.HTTPRouteFilterList{}
+ if err := r.client.List(context.Background(), routeFilterList, &client.ListOptions{
+ FieldSelector: fields.OneTermEqualSelector(configMapHTTPRouteFilterIndex, utils.NamespacedName(configMap).String()),
+ }); err != nil {
+ r.log.Error(err, "unable to find associated HTTPRouteFilter")
+ return false
+ }
+
+ if len(routeFilterList.Items) > 0 {
+ return true
+ }
}
- return true
+ return false
}
func (r *gatewayAPIReconciler) isEnvoyExtensionPolicyReferencingBackend(nsName *types.NamespacedName) bool {
@@ -648,3 +786,29 @@ func (r *gatewayAPIReconciler) isExtensionPolicyReferencingSecret(nsName *types.
return len(eepList.Items) > 0
}
+
+// isRouteReferencingHTTPRouteFilter returns true if the HTTPRouteFilter is referenced by an HTTPRoute
+func (r *gatewayAPIReconciler) isRouteReferencingHTTPRouteFilter(nsName *types.NamespacedName) bool {
+ ctx := context.Background()
+ httpRouteList := &gwapiv1.HTTPRouteList{}
+ if err := r.client.List(ctx, httpRouteList, &client.ListOptions{
+ FieldSelector: fields.OneTermEqualSelector(httpRouteFilterHTTPRouteIndex, nsName.String()),
+ }); err != nil {
+ r.log.Error(err, "unable to find associated HTTPRoutes")
+ return false
+ }
+
+ return len(httpRouteList.Items) != 0
+}
+
+// validateHTTPRouteFilterForReconcile tries finding the referencing HTTPRoute of the filter
+func (r *gatewayAPIReconciler) validateHTTPRouteFilterForReconcile(obj client.Object) bool {
+ hrf, ok := obj.(*egv1a1.HTTPRouteFilter)
+ if !ok {
+ r.log.Info("unexpected object type, bypassing reconciliation", "object", obj)
+ return false
+ }
+
+ nsName := utils.NamespacedName(hrf)
+ return r.isRouteReferencingHTTPRouteFilter(&nsName)
+}
diff --git a/internal/provider/kubernetes/predicates_test.go b/internal/provider/kubernetes/predicates_test.go
index 6379263bdb0..8ff155f46f4 100644
--- a/internal/provider/kubernetes/predicates_test.go
+++ b/internal/provider/kubernetes/predicates_test.go
@@ -19,13 +19,14 @@ import (
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
- gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy"
"github.com/envoyproxy/gateway/internal/logging"
+ "github.com/envoyproxy/gateway/internal/message"
"github.com/envoyproxy/gateway/internal/provider/kubernetes/test"
)
@@ -59,7 +60,6 @@ func TestGatewayClassHasMatchingController(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
res := r.hasMatchingController(tc.gc)
require.Equal(t, tc.expect, res)
@@ -107,8 +107,6 @@ func TestGatewayClassHasMatchingNamespaceLabels(t *testing.T) {
logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
for _, tc := range testCases {
- tc := tc
-
r := gatewayAPIReconciler{
classController: egv1a1.GatewayControllerName,
namespaceLabel: &metav1.LabelSelector{MatchExpressions: matchExpressions(tc.namespaceLabels, metav1.LabelSelectorOpExists, []string{})},
@@ -126,15 +124,10 @@ func TestGatewayClassHasMatchingNamespaceLabels(t *testing.T) {
}
t.Run(tc.name, func(t *testing.T) {
res := r.hasMatchingNamespaceLabels(
- test.GetHTTPRoute(
- types.NamespacedName{
- Namespace: ns,
- Name: "httproute-test",
- },
- "scheduled-status-test",
- types.NamespacedName{Name: "service"},
- 80,
- ))
+ test.GetHTTPRoute(types.NamespacedName{
+ Namespace: ns,
+ Name: "httproute-test",
+ }, "scheduled-status-test", types.NamespacedName{Name: "service"}, 80, ""))
require.Equal(t, tc.expect, res)
})
}
@@ -172,7 +165,6 @@ func TestValidateGatewayForReconcile(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().WithScheme(envoygateway.GetScheme()).WithObjects(tc.configs...).Build()
t.Run(tc.name, func(t *testing.T) {
res := r.validateGatewayForReconcile(tc.gateway)
@@ -225,7 +217,7 @@ func TestValidateSecretForReconcile(t *testing.T) {
configs: []client.Object{
test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil),
test.GetSecureGateway(types.NamespacedName{Name: "scheduled-status-test"}, "test-gc", test.GroupKindNamespacedName{
- Kind: gatewayapi.KindSecret,
+ Kind: resource.KindSecret,
Name: "secret",
}),
},
@@ -237,7 +229,7 @@ func TestValidateSecretForReconcile(t *testing.T) {
configs: []client.Object{
test.GetGatewayClass("test-gc", "not.configured/controller", nil),
test.GetSecureGateway(types.NamespacedName{Name: "scheduled-status-test"}, "test-gc", test.GroupKindNamespacedName{
- Kind: gatewayapi.KindSecret,
+ Kind: resource.KindSecret,
Name: "secret",
}),
},
@@ -269,7 +261,7 @@ func TestValidateSecretForReconcile(t *testing.T) {
TokenEndpoint: ptr.To("https://oauth2.googleapis.com/token"),
},
ClientID: "client-id",
- ClientSecret: gwapiv1b1.SecretObjectReference{
+ ClientSecret: gwapiv1.SecretObjectReference{
Name: "secret",
},
},
@@ -298,7 +290,7 @@ func TestValidateSecretForReconcile(t *testing.T) {
},
},
BasicAuth: &egv1a1.BasicAuth{
- Users: gwapiv1b1.SecretObjectReference{
+ Users: gwapiv1.SecretObjectReference{
Name: "secret",
},
},
@@ -344,7 +336,7 @@ func TestValidateSecretForReconcile(t *testing.T) {
Type: egv1a1.ImageWasmCodeSourceType,
Image: &egv1a1.ImageWasmCodeSource{
URL: "https://example.com/testwasm:v1.0.0",
- PullSecretRef: &gwapiv1b1.SecretObjectReference{
+ PullSecretRef: &gwapiv1.SecretObjectReference{
Name: "secret",
},
},
@@ -365,10 +357,12 @@ func TestValidateSecretForReconcile(t *testing.T) {
r := gatewayAPIReconciler{
classController: egv1a1.GatewayControllerName,
log: logger,
+ spCRDExists: true,
+ epCRDExists: true,
+ eepCRDExists: true,
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().
WithScheme(envoygateway.GetScheme()).
WithObjects(tc.configs...).
@@ -409,7 +403,7 @@ func TestValidateEndpointSliceForReconcile(t *testing.T) {
configs: []client.Object{
test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil),
sampleGateway,
- test.GetHTTPRoute(types.NamespacedName{Name: "httproute-test"}, "scheduled-status-test", types.NamespacedName{Name: "service"}, 80),
+ test.GetHTTPRoute(types.NamespacedName{Name: "httproute-test"}, "scheduled-status-test", types.NamespacedName{Name: "service"}, 80, ""),
},
endpointSlice: test.GetEndpointSlice(types.NamespacedName{Name: "endpointslice"}, "other-service"),
expect: false,
@@ -419,7 +413,7 @@ func TestValidateEndpointSliceForReconcile(t *testing.T) {
configs: []client.Object{
test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil),
sampleGateway,
- test.GetHTTPRoute(types.NamespacedName{Name: "httproute-test"}, "scheduled-status-test", types.NamespacedName{Name: "service"}, 80),
+ test.GetHTTPRoute(types.NamespacedName{Name: "httproute-test"}, "scheduled-status-test", types.NamespacedName{Name: "service"}, 80, ""),
},
endpointSlice: test.GetEndpointSlice(types.NamespacedName{Name: "endpointslice"}, "service"),
expect: true,
@@ -435,7 +429,6 @@ func TestValidateEndpointSliceForReconcile(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().
WithScheme(envoygateway.GetScheme()).
WithObjects(tc.configs...).
@@ -471,12 +464,14 @@ func TestValidateServiceForReconcile(t *testing.T) {
{
Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry,
OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "otel-collector",
- Namespace: ptr.To(gwapiv1.Namespace("default")),
- Port: ptr.To(gwapiv1.PortNumber(4317)),
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "otel-collector",
+ Namespace: ptr.To(gwapiv1.Namespace("default")),
+ Port: ptr.To(gwapiv1.PortNumber(4317)),
+ },
},
},
},
@@ -491,12 +486,14 @@ func TestValidateServiceForReconcile(t *testing.T) {
{
Type: egv1a1.MetricSinkTypeOpenTelemetry,
OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "otel-collector",
- Namespace: ptr.To(gwapiv1.Namespace("default")),
- Port: ptr.To(gwapiv1.PortNumber(4317)),
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "otel-collector",
+ Namespace: ptr.To(gwapiv1.Namespace("default")),
+ Port: ptr.To(gwapiv1.PortNumber(4317)),
+ },
},
},
},
@@ -507,12 +504,14 @@ func TestValidateServiceForReconcile(t *testing.T) {
Tracing: &egv1a1.ProxyTracing{
Provider: egv1a1.TracingProvider{
Type: egv1a1.TracingProviderTypeOpenTelemetry,
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "otel-collector",
- Namespace: ptr.To(gwapiv1.Namespace("default")),
- Port: ptr.To(gwapiv1.PortNumber(4317)),
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "otel-collector",
+ Namespace: ptr.To(gwapiv1.Namespace("default")),
+ Port: ptr.To(gwapiv1.PortNumber(4317)),
+ },
},
},
},
@@ -529,7 +528,7 @@ func TestValidateServiceForReconcile(t *testing.T) {
expect bool
}{
{
- name: "gateway service but deployment does not exist",
+ name: "gateway service but deployment or daemonset does not exist",
configs: []client.Object{
test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil),
sampleGateway,
@@ -551,7 +550,22 @@ func TestValidateServiceForReconcile(t *testing.T) {
gatewayapi.OwningGatewayNameLabel: "scheduled-status-test",
gatewayapi.OwningGatewayNamespaceLabel: "default",
}, nil),
- // Note that in case when a deployment exists, the Service is just processed for Gateway status
+ // Note that in case when a envoyObjects exists, the Service is just processed for Gateway status
+ // updates and not reconciled further.
+ expect: false,
+ },
+ {
+ name: "gateway service daemonset also exist",
+ configs: []client.Object{
+ test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil),
+ sampleGateway,
+ test.GetGatewayDaemonSet(types.NamespacedName{Name: proxy.ExpectedResourceHashedName("default/scheduled-status-test")}, nil),
+ },
+ service: test.GetService(types.NamespacedName{Name: "service"}, map[string]string{
+ gatewayapi.OwningGatewayNameLabel: "scheduled-status-test",
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ }, nil),
+ // Note that in case when a envoyObjects exists, the Service is just processed for Gateway status
// updates and not reconciled further.
expect: false,
},
@@ -569,7 +583,7 @@ func TestValidateServiceForReconcile(t *testing.T) {
configs: []client.Object{
test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil),
sampleGateway,
- test.GetHTTPRoute(types.NamespacedName{Name: "httproute-test"}, "scheduled-status-test", types.NamespacedName{Name: "service"}, 80),
+ test.GetHTTPRoute(types.NamespacedName{Name: "httproute-test"}, "scheduled-status-test", types.NamespacedName{Name: "service"}, 80, ""),
},
service: test.GetService(types.NamespacedName{Name: "service"}, nil, nil),
expect: true,
@@ -581,7 +595,7 @@ func TestValidateServiceForReconcile(t *testing.T) {
name: "route service routes exist but with non-existing gateway reference",
configs: []client.Object{
test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil),
- test.GetHTTPRoute(types.NamespacedName{Name: "httproute-test"}, "scheduled-status-test", types.NamespacedName{Name: "service"}, 80),
+ test.GetHTTPRoute(types.NamespacedName{Name: "httproute-test"}, "scheduled-status-test", types.NamespacedName{Name: "service"}, 80, ""),
},
service: test.GetService(types.NamespacedName{Name: "service"}, nil, nil),
expect: true,
@@ -675,10 +689,12 @@ func TestValidateServiceForReconcile(t *testing.T) {
},
ExtAuth: &egv1a1.ExtAuth{
HTTP: &egv1a1.HTTPExtAuthService{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "ext-auth-http-service",
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "ext-auth-http-service",
+ },
},
},
},
@@ -708,10 +724,12 @@ func TestValidateServiceForReconcile(t *testing.T) {
},
ExtAuth: &egv1a1.ExtAuth{
GRPC: &egv1a1.GRPCExtAuthService{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "ext-auth-grpc-service",
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "ext-auth-grpc-service",
+ },
},
},
},
@@ -741,10 +759,12 @@ func TestValidateServiceForReconcile(t *testing.T) {
},
ExtProc: []egv1a1.ExtProc{
{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "ext-proc-service",
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "ext-proc-service",
+ },
},
},
},
@@ -774,10 +794,12 @@ func TestValidateServiceForReconcile(t *testing.T) {
},
ExtProc: []egv1a1.ExtProc{
{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "ext-proc-service",
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "ext-proc-service",
+ },
},
},
},
@@ -830,13 +852,20 @@ func TestValidateServiceForReconcile(t *testing.T) {
logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
r := gatewayAPIReconciler{
- classController: egv1a1.GatewayControllerName,
- log: logger,
- mergeGateways: sets.New[string]("test-mg"),
+ classController: egv1a1.GatewayControllerName,
+ log: logger,
+ mergeGateways: sets.New[string]("test-mg"),
+ resources: &message.ProviderResources{},
+ grpcRouteCRDExists: true,
+ tcpRouteCRDExists: true,
+ udpRouteCRDExists: true,
+ tlsRouteCRDExists: true,
+ spCRDExists: true,
+ eepCRDExists: true,
+ epCRDExists: true,
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().
WithScheme(envoygateway.GetScheme()).
WithObjects(tc.configs...).
@@ -856,34 +885,39 @@ func TestValidateServiceForReconcile(t *testing.T) {
}
}
-// TestValidateDeploymentForReconcile tests the validateDeploymentForReconcile
+// TestValidateObjectForReconcile tests the validateObjectForReconcile
// predicate function.
-func TestValidateDeploymentForReconcile(t *testing.T) {
+func TestValidateObjectForReconcile(t *testing.T) {
sampleGateway := test.GetGateway(types.NamespacedName{Namespace: "default", Name: "scheduled-status-test"}, "test-gc", 8080)
mergeGatewaysConfig := test.GetEnvoyProxy(types.NamespacedName{Namespace: "default", Name: "merge-gateways-config"}, true)
testCases := []struct {
- name string
- configs []client.Object
- deployment client.Object
- expect bool
+ name string
+ configs []client.Object
+ envoyObjects []client.Object
+ expect bool
}{
{
- // No config should lead to a reconciliation of a Deployment object. The main
- // purpose of the Deployment watcher is just for update Gateway object statuses.
- name: "gateway deployment deployment also exist",
+ // No config should lead to a reconciliation of a Deployment or DaemonSet object. The main
+ // purpose of the watcher is just for updating Gateway object statuses.
+ name: "gateway deployment or daemonset also exist",
configs: []client.Object{
test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil),
sampleGateway,
- test.GetService(types.NamespacedName{Name: "deployment"}, map[string]string{
+ test.GetService(types.NamespacedName{Name: "envoyObjects"}, map[string]string{
gatewayapi.OwningGatewayNameLabel: "scheduled-status-test",
gatewayapi.OwningGatewayNamespaceLabel: "default",
}, nil),
},
- deployment: test.GetGatewayDeployment(types.NamespacedName{Name: "deployment"}, map[string]string{
- gatewayapi.OwningGatewayNameLabel: "scheduled-status-test",
- gatewayapi.OwningGatewayNamespaceLabel: "default",
- }),
+ envoyObjects: []client.Object{
+ test.GetGatewayDeployment(types.NamespacedName{Name: "deployment"}, map[string]string{
+ gatewayapi.OwningGatewayNameLabel: "scheduled-status-test",
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ }), test.GetGatewayDaemonSet(types.NamespacedName{Name: "daemonset"}, map[string]string{
+ gatewayapi.OwningGatewayNameLabel: "scheduled-status-test",
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ }),
+ },
expect: false,
},
{
@@ -897,9 +931,14 @@ func TestValidateDeploymentForReconcile(t *testing.T) {
}),
mergeGatewaysConfig,
},
- deployment: test.GetGatewayDeployment(types.NamespacedName{Name: "deployment"}, map[string]string{
- gatewayapi.OwningGatewayClassLabel: "test-mg",
- }),
+ envoyObjects: []client.Object{
+ test.GetGatewayDeployment(types.NamespacedName{Name: "deployment"}, map[string]string{
+ gatewayapi.OwningGatewayClassLabel: "test-mg",
+ }),
+ test.GetGatewayDaemonSet(types.NamespacedName{Name: "daemonset"}, map[string]string{
+ gatewayapi.OwningGatewayClassLabel: "test-mg",
+ }),
+ },
expect: false,
},
{
@@ -916,9 +955,14 @@ func TestValidateDeploymentForReconcile(t *testing.T) {
test.GetGateway(types.NamespacedName{Name: "merged-gateway-2", Namespace: "default"}, "test-mg", 8082),
test.GetGateway(types.NamespacedName{Name: "merged-gateway-3", Namespace: "default"}, "test-mg", 8083),
},
- deployment: test.GetGatewayDeployment(types.NamespacedName{Name: "deployment"}, map[string]string{
- gatewayapi.OwningGatewayClassLabel: "test-mg",
- }),
+ envoyObjects: []client.Object{
+ test.GetGatewayDeployment(types.NamespacedName{Name: "deployment"}, map[string]string{
+ gatewayapi.OwningGatewayClassLabel: "test-mg",
+ }),
+ test.GetGatewayDaemonSet(types.NamespacedName{Name: "daemonset"}, map[string]string{
+ gatewayapi.OwningGatewayClassLabel: "test-mg",
+ }),
+ },
expect: false,
},
}
@@ -930,14 +974,16 @@ func TestValidateDeploymentForReconcile(t *testing.T) {
classController: egv1a1.GatewayControllerName,
log: logger,
mergeGateways: sets.New[string]("test-mg"),
+ resources: &message.ProviderResources{},
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().WithScheme(envoygateway.GetScheme()).WithObjects(tc.configs...).Build()
t.Run(tc.name, func(t *testing.T) {
- res := r.validateDeploymentForReconcile(tc.deployment)
- require.Equal(t, tc.expect, res)
+ for _, obj := range tc.envoyObjects {
+ res := r.validateObjectForReconcile(obj)
+ require.Equal(t, tc.expect, res)
+ }
})
}
}
@@ -959,18 +1005,13 @@ func TestCheckObjectNamespaceLabels(t *testing.T) {
}{
{
name: "matching labels of namespace of the object is a subset of namespaceLabels",
- object: test.GetHTTPRoute(
- types.NamespacedName{
- Name: "foo-route",
- Namespace: "foo",
- },
- "eg",
- types.NamespacedName{
- Name: "foo-svc",
- Namespace: "foo",
- },
- 8080,
- ),
+ object: test.GetHTTPRoute(types.NamespacedName{
+ Name: "foo-route",
+ Namespace: "foo",
+ }, "eg", types.NamespacedName{
+ Name: "foo-svc",
+ Namespace: "foo",
+ }, 8080, ""),
ns: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
@@ -984,18 +1025,13 @@ func TestCheckObjectNamespaceLabels(t *testing.T) {
},
{
name: "non-matching labels of namespace of the object is a subset of namespaceLabels",
- object: test.GetHTTPRoute(
- types.NamespacedName{
- Name: "bar-route",
- Namespace: "bar",
- },
- "eg",
- types.NamespacedName{
- Name: "bar-svc",
- Namespace: "bar",
- },
- 8080,
- ),
+ object: test.GetHTTPRoute(types.NamespacedName{
+ Name: "bar-route",
+ Namespace: "bar",
+ }, "eg", types.NamespacedName{
+ Name: "bar-svc",
+ Namespace: "bar",
+ }, 8080, ""),
ns: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
@@ -1039,7 +1075,6 @@ func TestCheckObjectNamespaceLabels(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().WithObjects(tc.ns).Build()
r.namespaceLabel = &metav1.LabelSelector{MatchExpressions: matchExpressions(tc.reconcileLabels, metav1.LabelSelectorOpExists, []string{})}
ok, err := r.checkObjectNamespaceLabels(tc.object)
@@ -1143,3 +1178,64 @@ func TestMatchLabelsAndExpressions(t *testing.T) {
})
}
}
+
+// TestValidateHTTPRouteFilerForReconcile tests the vlidateHTTPRouteFilerForReconcile
+// predicate function.
+func TestValidateHTTPRouteFilerForReconcile(t *testing.T) {
+ sampleGWC := test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil)
+ sampleGateway := test.GetGateway(types.NamespacedName{Namespace: "default", Name: "scheduled-status-test"}, "test-gc", 8080)
+ sampleService := test.GetService(types.NamespacedName{Name: "service"}, nil, nil)
+ sampleHTTPRouteFilter := test.GetHTTPRouteFilter(types.NamespacedName{Name: "httproutefilter"})
+
+ testCases := []struct {
+ name string
+ configs []client.Object
+ httpRouteFilter client.Object
+ expect bool
+ }{
+ {
+ name: "httproutefilter but not referenced by route",
+ configs: []client.Object{
+ sampleGWC,
+ sampleGateway,
+ sampleService,
+ sampleHTTPRouteFilter,
+ },
+ httpRouteFilter: sampleHTTPRouteFilter,
+ expect: false,
+ },
+ {
+ name: "httproutefitler referenced by route",
+ configs: []client.Object{
+ sampleGWC,
+ sampleGateway,
+ sampleService,
+ sampleHTTPRouteFilter,
+ test.GetHTTPRoute(types.NamespacedName{Name: "httproute-test"}, "scheduled-status-test", types.NamespacedName{Name: "service"}, 80, "httproutefilter"),
+ },
+ httpRouteFilter: sampleHTTPRouteFilter,
+ expect: true,
+ },
+ }
+
+ // Create the reconciler.
+ logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+
+ r := gatewayAPIReconciler{
+ classController: egv1a1.GatewayControllerName,
+ log: logger,
+ }
+
+ for _, tc := range testCases {
+ r.client = fakeclient.NewClientBuilder().
+ WithScheme(envoygateway.GetScheme()).
+ WithObjects(tc.configs...).
+ WithIndex(&gwapiv1.HTTPRoute{}, backendHTTPRouteIndex, backendHTTPRouteIndexFunc).
+ WithIndex(&gwapiv1.HTTPRoute{}, httpRouteFilterHTTPRouteIndex, httpRouteFilterHTTPRouteIndexFunc).
+ Build()
+ t.Run(tc.name, func(t *testing.T) {
+ res := r.validateHTTPRouteFilterForReconcile(tc.httpRouteFilter)
+ require.Equal(t, tc.expect, res)
+ })
+ }
+}
diff --git a/internal/provider/kubernetes/resource.go b/internal/provider/kubernetes/resource.go
new file mode 100644
index 00000000000..b867d6319d3
--- /dev/null
+++ b/internal/provider/kubernetes/resource.go
@@ -0,0 +1,95 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package kubernetes
+
+import (
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/util/sets"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/utils"
+)
+
+type resourceMappings struct {
+ // Set for storing Gateways' NamespacedNames.
+ allAssociatedGateways sets.Set[string]
+ // Set for storing ReferenceGrants' NamespacedNames.
+ allAssociatedReferenceGrants sets.Set[string]
+ // Set for storing ServiceImports' NamespacedNames.
+ allAssociatedServiceImports sets.Set[string]
+ // Set for storing EndpointSlices' NamespacedNames.
+ allAssociatedEndpointSlices sets.Set[string]
+ // Set for storing Backends' NamespacedNames.
+ allAssociatedBackends sets.Set[string]
+ // Set for storing Secrets' NamespacedNames.
+ allAssociatedSecrets sets.Set[string]
+ // Set for storing ConfigMaps' NamespacedNames.
+ allAssociatedConfigMaps sets.Set[string]
+ // Set for storing namespaces for Route, Service and Gateway objects.
+ allAssociatedNamespaces sets.Set[string]
+ // Set for storing EnvoyProxies' NamespacedNames attaching to Gateway or GatewayClass.
+ allAssociatedEnvoyProxies sets.Set[string]
+ // Set for storing EnvoyPatchPolicies' NamespacedNames attaching to Gateway.
+ allAssociatedEnvoyPatchPolicies sets.Set[string]
+ // Set for storing TLSRoutes' NamespacedNames attaching to various Gateway objects.
+ allAssociatedTLSRoutes sets.Set[string]
+ // Set for storing HTTPRoutes' NamespacedNames attaching to various Gateway objects.
+ allAssociatedHTTPRoutes sets.Set[string]
+ // Set for storing GRPCRoutes' NamespacedNames attaching to various Gateway objects.
+ allAssociatedGRPCRoutes sets.Set[string]
+ // Set for storing TCPRoutes' NamespacedNames attaching to various Gateway objects.
+ allAssociatedTCPRoutes sets.Set[string]
+ // Set for storing UDPRoutes' NamespacedNames attaching to various Gateway objects.
+ allAssociatedUDPRoutes sets.Set[string]
+ // Set for storing backendRefs' BackendObjectReference referred by various Route objects.
+ allAssociatedBackendRefs sets.Set[gwapiv1.BackendObjectReference]
+ // Set for storing ClientTrafficPolicies' NamespacedNames referred by various Route objects.
+ allAssociatedClientTrafficPolicies sets.Set[string]
+ // Set for storing BackendTrafficPolicies' NamespacedNames referred by various Route objects.
+ allAssociatedBackendTrafficPolicies sets.Set[string]
+ // Set for storing SecurityPolicies' NamespacedNames referred by various Route objects.
+ allAssociatedSecurityPolicies sets.Set[string]
+ // Set for storing BackendTLSPolicies' NamespacedNames referred by various Backend objects.
+ allAssociatedBackendTLSPolicies sets.Set[string]
+ // Set for storing EnvoyExtensionPolicies' NamespacedNames attaching to various Gateway objects.
+ allAssociatedEnvoyExtensionPolicies sets.Set[string]
+ // extensionRefFilters is a map of filters managed by an extension.
+ // The key is the namespaced name, group and kind of the filter and the value is the
+ // unstructured form of the resource.
+ extensionRefFilters map[utils.NamespacedNameWithGroupKind]unstructured.Unstructured
+ // httpRouteFilters is a map of HTTPRouteFilters, where the key is the namespaced name,
+ // group and kind of the HTTPFilter.
+ httpRouteFilters map[utils.NamespacedNameWithGroupKind]*egv1a1.HTTPRouteFilter
+}
+
+func newResourceMapping() *resourceMappings {
+ return &resourceMappings{
+ allAssociatedGateways: sets.New[string](),
+ allAssociatedReferenceGrants: sets.New[string](),
+ allAssociatedServiceImports: sets.New[string](),
+ allAssociatedEndpointSlices: sets.New[string](),
+ allAssociatedBackends: sets.New[string](),
+ allAssociatedSecrets: sets.New[string](),
+ allAssociatedConfigMaps: sets.New[string](),
+ allAssociatedNamespaces: sets.New[string](),
+ allAssociatedEnvoyProxies: sets.New[string](),
+ allAssociatedEnvoyPatchPolicies: sets.New[string](),
+ allAssociatedTLSRoutes: sets.New[string](),
+ allAssociatedHTTPRoutes: sets.New[string](),
+ allAssociatedGRPCRoutes: sets.New[string](),
+ allAssociatedTCPRoutes: sets.New[string](),
+ allAssociatedUDPRoutes: sets.New[string](),
+ allAssociatedBackendRefs: sets.New[gwapiv1.BackendObjectReference](),
+ allAssociatedClientTrafficPolicies: sets.New[string](),
+ allAssociatedBackendTrafficPolicies: sets.New[string](),
+ allAssociatedSecurityPolicies: sets.New[string](),
+ allAssociatedBackendTLSPolicies: sets.New[string](),
+ allAssociatedEnvoyExtensionPolicies: sets.New[string](),
+ extensionRefFilters: map[utils.NamespacedNameWithGroupKind]unstructured.Unstructured{},
+ httpRouteFilters: map[utils.NamespacedNameWithGroupKind]*egv1a1.HTTPRouteFilter{},
+ }
+}
diff --git a/internal/provider/kubernetes/routes.go b/internal/provider/kubernetes/routes.go
index ad2638684cd..fa148ffd441 100644
--- a/internal/provider/kubernetes/routes.go
+++ b/internal/provider/kubernetes/routes.go
@@ -16,14 +16,16 @@ import (
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/utils"
)
// processTLSRoutes finds TLSRoutes corresponding to a gatewayNamespaceName, further checks for
// the backend references and pushes the TLSRoutes to the resourceTree.
func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayNamespaceName string,
- resourceMap *resourceMappings, resourceTree *gatewayapi.Resources,
+ resourceMap *resourceMappings, resourceTree *resource.Resources,
) error {
tlsRouteList := &gwapiv1a2.TLSRouteList{}
if err := r.client.List(ctx, tlsRouteList, &client.ListOptions{
@@ -34,7 +36,7 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName
}
for _, tlsRoute := range tlsRouteList.Items {
- tlsRoute := tlsRoute
+ tlsRoute := tlsRoute //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(&tlsRoute); err != nil {
r.log.Error(err, "failed to check namespace labels for TLSRoute %s in namespace %s: %w", tlsRoute.GetName(), tlsRoute.GetNamespace())
@@ -54,9 +56,7 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName
for _, rule := range tlsRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
- ref := gatewayapi.UpgradeBackendRef(backendRef)
- if err := validateBackendRef(&ref); err != nil {
+ if err := validateBackendRef(&backendRef); err != nil {
r.log.Error(err, "invalid backendRef")
continue
}
@@ -70,8 +70,8 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName
})
if backendNamespace != tlsRoute.Namespace {
- from := ObjectKindNamespacedName{kind: gatewayapi.KindTLSRoute, namespace: tlsRoute.Namespace, name: tlsRoute.Name}
- to := ObjectKindNamespacedName{kind: gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService), namespace: backendNamespace, name: string(backendRef.Name)}
+ from := ObjectKindNamespacedName{kind: resource.KindTLSRoute, namespace: tlsRoute.Namespace, name: tlsRoute.Name}
+ to := ObjectKindNamespacedName{kind: gatewayapi.KindDerefOr(backendRef.Kind, resource.KindService), namespace: backendNamespace, name: string(backendRef.Name)}
refGrant, err := r.findReferenceGrant(ctx, from, to)
switch {
case err != nil:
@@ -80,9 +80,13 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
- resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
- r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
- "name", refGrant.Name)
+ refGrantNamespacedName := utils.NamespacedName(refGrant).String()
+ if !resourceMap.allAssociatedReferenceGrants.Has(refGrantNamespacedName) {
+ resourceMap.allAssociatedReferenceGrants.Insert(refGrantNamespacedName)
+ resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
+ r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
+ "name", refGrant.Name)
+ }
}
}
}
@@ -102,7 +106,7 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName
// processGRPCRoutes finds GRPCRoutes corresponding to a gatewayNamespaceName, further checks for
// the backend references and pushes the GRPCRoutes to the resourceTree.
func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNamespaceName string,
- resourceMap *resourceMappings, resourceTree *gatewayapi.Resources,
+ resourceMap *resourceMappings, resourceTree *resource.Resources,
) error {
grpcRouteList := &gwapiv1.GRPCRouteList{}
@@ -114,7 +118,7 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam
}
for _, grpcRoute := range grpcRouteList.Items {
- grpcRoute := grpcRoute
+ grpcRoute := grpcRoute //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(&grpcRoute); err != nil {
r.log.Error(err, "failed to check namespace labels for GRPCRoute %s in namespace %s: %w", grpcRoute.GetName(), grpcRoute.GetNamespace())
@@ -134,7 +138,6 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam
for _, rule := range grpcRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
if err := validateBackendRef(&backendRef.BackendRef); err != nil {
r.log.Error(err, "invalid backendRef")
continue
@@ -150,12 +153,12 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam
if backendNamespace != grpcRoute.Namespace {
from := ObjectKindNamespacedName{
- kind: gatewayapi.KindGRPCRoute,
+ kind: resource.KindGRPCRoute,
namespace: grpcRoute.Namespace,
name: grpcRoute.Name,
}
to := ObjectKindNamespacedName{
- kind: gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService),
+ kind: gatewayapi.KindDerefOr(backendRef.Kind, resource.KindService),
namespace: backendNamespace,
name: string(backendRef.Name),
}
@@ -167,9 +170,13 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
- resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
- r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
- "name", refGrant.Name)
+ refGrantNamespacedName := utils.NamespacedName(refGrant).String()
+ if !resourceMap.allAssociatedReferenceGrants.Has(refGrantNamespacedName) {
+ resourceMap.allAssociatedReferenceGrants.Insert(refGrantNamespacedName)
+ resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
+ r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
+ "name", refGrant.Name)
+ }
}
}
}
@@ -228,9 +235,21 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam
// processHTTPRoutes finds HTTPRoutes corresponding to a gatewayNamespaceName, further checks for
// the backend references and pushes the HTTPRoutes to the resourceTree.
func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNamespaceName string,
- resourceMap *resourceMappings, resourceTree *gatewayapi.Resources,
+ resourceMap *resourceMappings, resourceTree *resource.Resources,
) error {
httpRouteList := &gwapiv1.HTTPRouteList{}
+ if r.hrfCRDExists {
+ httpFilters, err := r.getHTTPRouteFilters(ctx)
+ if err != nil {
+ return err
+ }
+
+ for i := range httpFilters {
+ filter := httpFilters[i]
+ resourceMap.httpRouteFilters[utils.GetNamespacedNameWithGroupKind(&filter)] = &filter
+ r.processRouteFilterConfigMapRef(ctx, &filter, resourceMap, resourceTree)
+ }
+ }
extensionRefFilters, err := r.getExtensionRefFilters(ctx)
if err != nil {
@@ -249,7 +268,7 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
}
for _, httpRoute := range httpRouteList.Items {
- httpRoute := httpRoute
+ httpRoute := httpRoute //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(&httpRoute); err != nil {
r.log.Error(err, "failed to check namespace labels for HTTPRoute %s in namespace %s: %w", httpRoute.GetName(), httpRoute.GetNamespace())
@@ -269,7 +288,6 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
for _, rule := range httpRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
if err := validateBackendRef(&backendRef.BackendRef); err != nil {
r.log.Error(err, "invalid backendRef")
continue
@@ -285,12 +303,12 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
if backendNamespace != httpRoute.Namespace {
from := ObjectKindNamespacedName{
- kind: gatewayapi.KindHTTPRoute,
+ kind: resource.KindHTTPRoute,
namespace: httpRoute.Namespace,
name: httpRoute.Name,
}
to := ObjectKindNamespacedName{
- kind: gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService),
+ kind: gatewayapi.KindDerefOr(backendRef.Kind, resource.KindService),
namespace: backendNamespace,
name: string(backendRef.Name),
}
@@ -302,9 +320,13 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
- resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
- r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
- "name", refGrant.Name)
+ refGrantNamespacedName := utils.NamespacedName(refGrant).String()
+ if !resourceMap.allAssociatedReferenceGrants.Has(refGrantNamespacedName) {
+ resourceMap.allAssociatedReferenceGrants.Insert(refGrantNamespacedName)
+ resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
+ r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
+ "name", refGrant.Name)
+ }
}
}
}
@@ -352,12 +374,12 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
if backendNamespace != httpRoute.Namespace {
from := ObjectKindNamespacedName{
- kind: gatewayapi.KindHTTPRoute,
+ kind: resource.KindHTTPRoute,
namespace: httpRoute.Namespace,
name: httpRoute.Name,
}
to := ObjectKindNamespacedName{
- kind: gatewayapi.KindDerefOr(mirrorBackendRef.Kind, gatewayapi.KindService),
+ kind: gatewayapi.KindDerefOr(mirrorBackendRef.Kind, resource.KindService),
namespace: backendNamespace,
name: string(mirrorBackendRef.Name),
}
@@ -369,9 +391,13 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
- resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
- r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
- "name", refGrant.Name)
+ refGrantNamespacedName := utils.NamespacedName(refGrant).String()
+ if !resourceMap.allAssociatedReferenceGrants.Has(refGrantNamespacedName) {
+ resourceMap.allAssociatedReferenceGrants.Insert(refGrantNamespacedName)
+ resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
+ r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
+ "name", refGrant.Name)
+ }
}
}
} else if filter.Type == gwapiv1.HTTPRouteFilterExtensionRef {
@@ -387,17 +413,28 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
Kind: string(filter.ExtensionRef.Kind),
},
}
- extRefFilter, ok := resourceMap.extensionRefFilters[key]
- if !ok {
- r.log.Error(
- errors.New("filter not found; bypassing rule"),
- "Filter not found; bypassing rule",
- "name", filter.ExtensionRef.Name,
- "index", i)
- continue
- }
- resourceTree.ExtensionRefFilters = append(resourceTree.ExtensionRefFilters, extRefFilter)
+ switch string(filter.ExtensionRef.Kind) {
+ case egv1a1.KindHTTPRouteFilter:
+ httpFilter, ok := resourceMap.httpRouteFilters[key]
+ if !ok {
+ r.log.Error(err, "HTTPRouteFilters not found; bypassing rule", "index", i)
+ continue
+ }
+ resourceTree.HTTPRouteFilters = append(resourceTree.HTTPRouteFilters, httpFilter)
+ default:
+ extRefFilter, ok := resourceMap.extensionRefFilters[key]
+ if !ok {
+ r.log.Error(
+ errors.New("filter not found; bypassing rule"),
+ "Filter not found; bypassing rule",
+ "name", filter.ExtensionRef.Name,
+ "index", i)
+ continue
+ }
+
+ resourceTree.ExtensionRefFilters = append(resourceTree.ExtensionRefFilters, extRefFilter)
+ }
}
}
}
@@ -416,7 +453,7 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
// processTCPRoutes finds TCPRoutes corresponding to a gatewayNamespaceName, further checks for
// the backend references and pushes the TCPRoutes to the resourceTree.
func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayNamespaceName string,
- resourceMap *resourceMappings, resourceTree *gatewayapi.Resources,
+ resourceMap *resourceMappings, resourceTree *resource.Resources,
) error {
tcpRouteList := &gwapiv1a2.TCPRouteList{}
if err := r.client.List(ctx, tcpRouteList, &client.ListOptions{
@@ -427,7 +464,7 @@ func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayName
}
for _, tcpRoute := range tcpRouteList.Items {
- tcpRoute := tcpRoute
+ tcpRoute := tcpRoute //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(&tcpRoute); err != nil {
r.log.Error(err, "failed to check namespace labels for TCPRoute %s in namespace %s: %w", tcpRoute.GetName(), tcpRoute.GetNamespace())
@@ -447,9 +484,7 @@ func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayName
for _, rule := range tcpRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
- ref := gatewayapi.UpgradeBackendRef(backendRef)
- if err := validateBackendRef(&ref); err != nil {
+ if err := validateBackendRef(&backendRef); err != nil {
r.log.Error(err, "invalid backendRef")
continue
}
@@ -463,8 +498,8 @@ func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayName
})
if backendNamespace != tcpRoute.Namespace {
- from := ObjectKindNamespacedName{kind: gatewayapi.KindTCPRoute, namespace: tcpRoute.Namespace, name: tcpRoute.Name}
- to := ObjectKindNamespacedName{kind: gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService), namespace: backendNamespace, name: string(backendRef.Name)}
+ from := ObjectKindNamespacedName{kind: resource.KindTCPRoute, namespace: tcpRoute.Namespace, name: tcpRoute.Name}
+ to := ObjectKindNamespacedName{kind: gatewayapi.KindDerefOr(backendRef.Kind, resource.KindService), namespace: backendNamespace, name: string(backendRef.Name)}
refGrant, err := r.findReferenceGrant(ctx, from, to)
switch {
case err != nil:
@@ -473,9 +508,13 @@ func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayName
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
- resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
- r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
- "name", refGrant.Name)
+ refGrantNamespacedName := utils.NamespacedName(refGrant).String()
+ if !resourceMap.allAssociatedReferenceGrants.Has(refGrantNamespacedName) {
+ resourceMap.allAssociatedReferenceGrants.Insert(refGrantNamespacedName)
+ resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
+ r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
+ "name", refGrant.Name)
+ }
}
}
}
@@ -495,7 +534,7 @@ func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayName
// processUDPRoutes finds UDPRoutes corresponding to a gatewayNamespaceName, further checks for
// the backend references and pushes the UDPRoutes to the resourceTree.
func (r *gatewayAPIReconciler) processUDPRoutes(ctx context.Context, gatewayNamespaceName string,
- resourceMap *resourceMappings, resourceTree *gatewayapi.Resources,
+ resourceMap *resourceMappings, resourceTree *resource.Resources,
) error {
udpRouteList := &gwapiv1a2.UDPRouteList{}
if err := r.client.List(ctx, udpRouteList, &client.ListOptions{
@@ -506,7 +545,7 @@ func (r *gatewayAPIReconciler) processUDPRoutes(ctx context.Context, gatewayName
}
for _, udpRoute := range udpRouteList.Items {
- udpRoute := udpRoute
+ udpRoute := udpRoute //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(&udpRoute); err != nil {
r.log.Error(err, "failed to check namespace labels for UDPRoute %s in namespace %s: %w", udpRoute.GetName(), udpRoute.GetNamespace())
@@ -526,9 +565,7 @@ func (r *gatewayAPIReconciler) processUDPRoutes(ctx context.Context, gatewayName
for _, rule := range udpRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
- ref := gatewayapi.UpgradeBackendRef(backendRef)
- if err := validateBackendRef(&ref); err != nil {
+ if err := validateBackendRef(&backendRef); err != nil {
r.log.Error(err, "invalid backendRef")
continue
}
@@ -542,8 +579,8 @@ func (r *gatewayAPIReconciler) processUDPRoutes(ctx context.Context, gatewayName
})
if backendNamespace != udpRoute.Namespace {
- from := ObjectKindNamespacedName{kind: gatewayapi.KindUDPRoute, namespace: udpRoute.Namespace, name: udpRoute.Name}
- to := ObjectKindNamespacedName{kind: gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService), namespace: backendNamespace, name: string(backendRef.Name)}
+ from := ObjectKindNamespacedName{kind: resource.KindUDPRoute, namespace: udpRoute.Namespace, name: udpRoute.Name}
+ to := ObjectKindNamespacedName{kind: gatewayapi.KindDerefOr(backendRef.Kind, resource.KindService), namespace: backendNamespace, name: string(backendRef.Name)}
refGrant, err := r.findReferenceGrant(ctx, from, to)
switch {
case err != nil:
@@ -552,9 +589,12 @@ func (r *gatewayAPIReconciler) processUDPRoutes(ctx context.Context, gatewayName
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
- resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
- r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
- "name", refGrant.Name)
+ if !resourceMap.allAssociatedReferenceGrants.Has(utils.NamespacedName(refGrant).String()) {
+ resourceMap.allAssociatedReferenceGrants.Insert(utils.NamespacedName(refGrant).String())
+ resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
+ r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
+ "name", refGrant.Name)
+ }
}
}
}
diff --git a/internal/provider/kubernetes/routes_test.go b/internal/provider/kubernetes/routes_test.go
index be6769589a1..5fc3654657b 100644
--- a/internal/provider/kubernetes/routes_test.go
+++ b/internal/provider/kubernetes/routes_test.go
@@ -25,6 +25,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway"
"github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/logging"
"github.com/envoyproxy/gateway/internal/utils"
)
@@ -107,7 +108,7 @@ func TestProcessHTTPRoutes(t *testing.T) {
BackendRef: gwapiv1.BackendRef{
BackendObjectReference: gwapiv1.BackendObjectReference{
Group: gatewayapi.GroupPtr(corev1.GroupName),
- Kind: gatewayapi.KindPtr(gatewayapi.KindService),
+ Kind: gatewayapi.KindPtr(resource.KindService),
Name: "test",
},
},
@@ -169,7 +170,7 @@ func TestProcessHTTPRoutes(t *testing.T) {
BackendRef: gwapiv1.BackendRef{
BackendObjectReference: gwapiv1.BackendObjectReference{
Group: gatewayapi.GroupPtr(corev1.GroupName),
- Kind: gatewayapi.KindPtr(gatewayapi.KindService),
+ Kind: gatewayapi.KindPtr(resource.KindService),
Name: "test",
},
},
@@ -257,7 +258,7 @@ func TestProcessHTTPRoutes(t *testing.T) {
BackendRef: gwapiv1.BackendRef{
BackendObjectReference: gwapiv1.BackendObjectReference{
Group: gatewayapi.GroupPtr(corev1.GroupName),
- Kind: gatewayapi.KindPtr(gatewayapi.KindService),
+ Kind: gatewayapi.KindPtr(resource.KindService),
Name: "test",
},
},
@@ -320,7 +321,7 @@ func TestProcessHTTPRoutes(t *testing.T) {
BackendRef: gwapiv1.BackendRef{
BackendObjectReference: gwapiv1.BackendObjectReference{
Group: gatewayapi.GroupPtr(corev1.GroupName),
- Kind: gatewayapi.KindPtr(gatewayapi.KindService),
+ Kind: gatewayapi.KindPtr(resource.KindService),
Name: "test",
},
},
@@ -382,7 +383,7 @@ func TestProcessHTTPRoutes(t *testing.T) {
}, defaultWait, defaultTick)
// Process the test case httproutes.
- resourceTree := gatewayapi.NewResources()
+ resourceTree := resource.NewResources()
resourceMap := newResourceMapping()
err := r.processHTTPRoutes(ctx, gwNsName, resourceMap, resourceTree)
if tc.expected {
@@ -478,7 +479,7 @@ func TestProcessGRPCRoutes(t *testing.T) {
BackendRef: gwapiv1.BackendRef{
BackendObjectReference: gwapiv1.BackendObjectReference{
Group: gatewayapi.GroupPtr(corev1.GroupName),
- Kind: gatewayapi.KindPtr(gatewayapi.KindService),
+ Kind: gatewayapi.KindPtr(resource.KindService),
Name: "test",
},
},
@@ -524,7 +525,7 @@ func TestProcessGRPCRoutes(t *testing.T) {
Build()
// Process the test case httproutes.
- resourceTree := gatewayapi.NewResources()
+ resourceTree := resource.NewResources()
resourceMap := newResourceMapping()
err := r.processGRPCRoutes(ctx, gwNsName, resourceMap, resourceTree)
if tc.expected {
@@ -851,7 +852,6 @@ func TestValidateHTTPRouteParentRefs(t *testing.T) {
ctx := context.Background()
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var objs []client.Object
for i := range tc.classes {
diff --git a/internal/provider/kubernetes/sources.go b/internal/provider/kubernetes/sources.go
index e19259f77ca..4c76820fdc2 100644
--- a/internal/provider/kubernetes/sources.go
+++ b/internal/provider/kubernetes/sources.go
@@ -13,6 +13,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
)
@@ -28,7 +29,7 @@ func NewWatchAndReconcileSource(cond <-chan struct{}, obj client.Object, eh hand
}
// Start implements the Source interface. It registers the EventHandler with the Informer.
-func (s *watchAndReconcileSource) Start(ctx context.Context, queue workqueue.RateLimitingInterface) error {
+func (s *watchAndReconcileSource) Start(ctx context.Context, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) error {
if s.object == nil {
return errors.New("object to queue is required")
}
diff --git a/internal/provider/kubernetes/sources_test.go b/internal/provider/kubernetes/sources_test.go
index aafc74bd2b6..18c5be0be8e 100644
--- a/internal/provider/kubernetes/sources_test.go
+++ b/internal/provider/kubernetes/sources_test.go
@@ -32,7 +32,7 @@ func TestSources(t *testing.T) {
expectedAddresses []string
handler handler.EventHandler
mapFunc handler.MapFunc
- queue workqueue.RateLimitingInterface
+ queue workqueue.TypedRateLimitingInterface[reconcile.Request]
expected bool
obj client.Object
}{
@@ -40,7 +40,7 @@ func TestSources(t *testing.T) {
name: "Queue size should increase by one after the condition event triggered",
expectedAddresses: []string{},
handler: handler.EnqueueRequestsFromMapFunc(enqueueClass),
- queue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()),
+ queue: workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[reconcile.Request]()),
ctx: context.Background(),
obj: &gwapiv1.GatewayClass{},
expected: true,
@@ -49,7 +49,7 @@ func TestSources(t *testing.T) {
name: "Confirm object is required",
expectedAddresses: []string{},
handler: handler.EnqueueRequestsFromMapFunc(enqueueClass),
- queue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()),
+ queue: workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[reconcile.Request]()),
ctx: context.Background(),
obj: nil,
expected: false,
diff --git a/internal/provider/kubernetes/status.go b/internal/provider/kubernetes/status.go
index 85e9ff99310..d9ff03f9b66 100644
--- a/internal/provider/kubernetes/status.go
+++ b/internal/provider/kubernetes/status.go
@@ -8,8 +8,8 @@ package kubernetes
import (
"context"
"fmt"
+ "reflect"
- kerrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -18,6 +18,7 @@ import (
gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/message"
"github.com/envoyproxy/gateway/internal/utils"
@@ -26,6 +27,35 @@ import (
// subscribeAndUpdateStatus subscribes to gateway API object status updates and
// writes it into the Kubernetes API Server.
func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, extensionManagerEnabled bool) {
+ // GatewayClass object status updater
+ go func() {
+ message.HandleSubscription(
+ message.Metadata{Runner: string(egv1a1.LogComponentProviderRunner), Message: "gatewayclass-status"},
+ r.resources.GatewayClassStatuses.Subscribe(ctx),
+ func(update message.Update[types.NamespacedName, *gwapiv1.GatewayClassStatus], errChan chan error) {
+ // skip delete updates.
+ if update.Delete {
+ return
+ }
+
+ r.statusUpdater.Send(Update{
+ NamespacedName: update.Key,
+ Resource: new(gwapiv1.GatewayClass),
+ Mutator: MutatorFunc(func(obj client.Object) client.Object {
+ gc, ok := obj.(*gwapiv1.GatewayClass)
+ if !ok {
+ panic(fmt.Sprintf("unsupported object type %T", obj))
+ }
+ gcCopy := gc.DeepCopy()
+ gcCopy.Status = *update.Value
+ return gcCopy
+ }),
+ })
+ },
+ )
+ r.log.Info("gatewayclass status subscriber shutting down")
+ }()
+
// Gateway object status updater
go func() {
message.HandleSubscription(
@@ -74,7 +104,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
panic(err)
}
hCopy := h.DeepCopy()
- hCopy.Status.Parents = val.Parents
+ hCopy.Status.Parents = mergeRouteParentStatus(h.Namespace, h.Status.Parents, val.Parents)
return hCopy
}),
})
@@ -97,15 +127,15 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
NamespacedName: key,
Resource: new(gwapiv1.GRPCRoute),
Mutator: MutatorFunc(func(obj client.Object) client.Object {
- h, ok := obj.(*gwapiv1.GRPCRoute)
+ g, ok := obj.(*gwapiv1.GRPCRoute)
if !ok {
err := fmt.Errorf("unsupported object type %T", obj)
errChan <- err
panic(err)
}
- hCopy := h.DeepCopy()
- hCopy.Status.Parents = val.Parents
- return hCopy
+ gCopy := g.DeepCopy()
+ gCopy.Status.Parents = mergeRouteParentStatus(g.Namespace, g.Status.Parents, val.Parents)
+ return gCopy
}),
})
},
@@ -136,7 +166,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
panic(err)
}
tCopy := t.DeepCopy()
- tCopy.Status.Parents = val.Parents
+ tCopy.Status.Parents = mergeRouteParentStatus(t.Namespace, t.Status.Parents, val.Parents)
return tCopy
}),
})
@@ -168,7 +198,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
panic(err)
}
tCopy := t.DeepCopy()
- tCopy.Status.Parents = val.Parents
+ tCopy.Status.Parents = mergeRouteParentStatus(t.Namespace, t.Status.Parents, val.Parents)
return tCopy
}),
})
@@ -193,15 +223,15 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
NamespacedName: key,
Resource: new(gwapiv1a2.UDPRoute),
Mutator: MutatorFunc(func(obj client.Object) client.Object {
- t, ok := obj.(*gwapiv1a2.UDPRoute)
+ u, ok := obj.(*gwapiv1a2.UDPRoute)
if !ok {
err := fmt.Errorf("unsupported object type %T", obj)
errChan <- err
panic(err)
}
- tCopy := t.DeepCopy()
- tCopy.Status.Parents = val.Parents
- return tCopy
+ uCopy := u.DeepCopy()
+ uCopy.Status.Parents = mergeRouteParentStatus(u.Namespace, u.Status.Parents, val.Parents)
+ return uCopy
}),
})
},
@@ -399,6 +429,38 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
r.log.Info("envoyExtensionPolicy status subscriber shutting down")
}()
+ // Backend object status updater
+ go func() {
+ message.HandleSubscription(
+ message.Metadata{Runner: string(egv1a1.LogComponentProviderRunner), Message: "backend-status"},
+ r.resources.BackendStatuses.Subscribe(ctx),
+ func(update message.Update[types.NamespacedName, *egv1a1.BackendStatus], errChan chan error) {
+ // skip delete updates.
+ if update.Delete {
+ return
+ }
+ key := update.Key
+ val := update.Value
+ r.statusUpdater.Send(Update{
+ NamespacedName: key,
+ Resource: new(egv1a1.Backend),
+ Mutator: MutatorFunc(func(obj client.Object) client.Object {
+ t, ok := obj.(*egv1a1.Backend)
+ if !ok {
+ err := fmt.Errorf("unsupported object type %T", obj)
+ errChan <- err
+ panic(err)
+ }
+ tCopy := t.DeepCopy()
+ tCopy.Status = *val
+ return tCopy
+ }),
+ })
+ },
+ )
+ r.log.Info("backend status subscriber shutting down")
+ }()
+
if extensionManagerEnabled {
// EnvoyExtensionPolicy object status updater
go func() {
@@ -437,14 +499,64 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
}
}
+// mergeRouteParentStatus merges the old and new RouteParentStatus.
+// This is needed because the RouteParentStatus doesn't support strategic merge patch yet.
+func mergeRouteParentStatus(ns string, old, new []gwapiv1.RouteParentStatus) []gwapiv1.RouteParentStatus {
+ merged := make([]gwapiv1.RouteParentStatus, len(old))
+ _ = copy(merged, old)
+ for _, parent := range new {
+ found := -1
+ for i, existing := range old {
+ if isParentRefEqual(parent.ParentRef, existing.ParentRef, ns) {
+ found = i
+ break
+ }
+ }
+ if found >= 0 {
+ merged[found] = parent
+ } else {
+ merged = append(merged, parent)
+ }
+ }
+ return merged
+}
+
+func isParentRefEqual(ref1, ref2 gwapiv1.ParentReference, routeNS string) bool {
+ defaultGroup := (*gwapiv1.Group)(&gwapiv1.GroupVersion.Group)
+ if ref1.Group == nil {
+ ref1.Group = defaultGroup
+ }
+ if ref2.Group == nil {
+ ref2.Group = defaultGroup
+ }
+
+ defaultKind := gwapiv1.Kind(resource.KindGateway)
+ if ref1.Kind == nil {
+ ref1.Kind = &defaultKind
+ }
+ if ref2.Kind == nil {
+ ref2.Kind = &defaultKind
+ }
+
+ // If the parent's namespace is not set, default to the namespace of the Route.
+ defaultNS := gwapiv1.Namespace(routeNS)
+ if ref1.Namespace == nil {
+ ref1.Namespace = &defaultNS
+ }
+ if ref2.Namespace == nil {
+ ref2.Namespace = &defaultNS
+ }
+ return reflect.DeepEqual(ref1, ref2)
+}
+
func (r *gatewayAPIReconciler) updateStatusForGateway(ctx context.Context, gtw *gwapiv1.Gateway) {
// nil check for unit tests.
if r.statusUpdater == nil {
return
}
- // Get deployment
- deploy, err := r.envoyDeploymentForGateway(ctx, gtw)
+ // Get envoyObjects
+ envoyObj, err := r.envoyObjectForGateway(ctx, gtw)
if err != nil {
r.log.Info("failed to get Deployment for gateway",
"namespace", gtw.Namespace, "name", gtw.Name)
@@ -459,7 +571,7 @@ func (r *gatewayAPIReconciler) updateStatusForGateway(ctx context.Context, gtw *
// update accepted condition
status.UpdateGatewayStatusAcceptedCondition(gtw, true)
// update address field and programmed condition
- status.UpdateGatewayStatusProgrammedCondition(gtw, svc, deploy, r.store.listNodeAddresses()...)
+ status.UpdateGatewayStatusProgrammedCondition(gtw, svc, envoyObj, r.store.listNodeAddresses()...)
key := utils.NamespacedName(gtw)
@@ -480,34 +592,3 @@ func (r *gatewayAPIReconciler) updateStatusForGateway(ctx context.Context, gtw *
}),
})
}
-
-func (r *gatewayAPIReconciler) updateStatusForGatewayClass(
- ctx context.Context,
- gc *gwapiv1.GatewayClass,
- accepted bool,
- reason,
- msg string,
-) error {
- if r.statusUpdater != nil {
- r.statusUpdater.Send(Update{
- NamespacedName: types.NamespacedName{Name: gc.Name},
- Resource: &gwapiv1.GatewayClass{},
- Mutator: MutatorFunc(func(obj client.Object) client.Object {
- gc, ok := obj.(*gwapiv1.GatewayClass)
- if !ok {
- panic(fmt.Sprintf("unsupported object type %T", obj))
- }
-
- return status.SetGatewayClassAccepted(gc.DeepCopy(), accepted, reason, msg)
- }),
- })
- } else {
- // this branch makes testing easier by not going through the status.Updater.
- duplicate := status.SetGatewayClassAccepted(gc.DeepCopy(), accepted, reason, msg)
-
- if err := r.client.Status().Update(ctx, duplicate); err != nil && !kerrors.IsNotFound(err) {
- return fmt.Errorf("error updating status of gatewayclass %s: %w", duplicate.Name, err)
- }
- }
- return nil
-}
diff --git a/internal/provider/kubernetes/status_test.go b/internal/provider/kubernetes/status_test.go
new file mode 100644
index 00000000000..5e81c46135e
--- /dev/null
+++ b/internal/provider/kubernetes/status_test.go
@@ -0,0 +1,294 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package kubernetes
+
+import (
+ "reflect"
+ "testing"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/utils/ptr"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+)
+
+func Test_mergeRouteParentStatus(t *testing.T) {
+ type args struct {
+ old []gwapiv1.RouteParentStatus
+ new []gwapiv1.RouteParentStatus
+ }
+ tests := []struct {
+ name string
+ args args
+ want []gwapiv1.RouteParentStatus
+ }{
+ {
+ name: "merge old and new",
+ args: args{
+ old: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway1",
+ Namespace: ptr.To[gwapiv1.Namespace]("default"),
+ SectionName: ptr.To[gwapiv1.SectionName]("listener1"),
+ Port: ptr.To[gwapiv1.PortNumber](80),
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
+ new: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionFalse,
+ Reason: "SomeReason",
+ },
+ },
+ },
+ },
+ },
+ want: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway1",
+ Namespace: ptr.To[gwapiv1.Namespace]("default"),
+ SectionName: ptr.To[gwapiv1.SectionName]("listener1"),
+ Port: ptr.To[gwapiv1.PortNumber](80),
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionFalse,
+ Reason: "SomeReason",
+ },
+ },
+ },
+ },
+ },
+
+ {
+ name: "override an existing parent",
+ args: args{
+ old: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway1",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ Namespace: ptr.To[gwapiv1.Namespace]("default"),
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
+ new: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionFalse,
+ Reason: "SomeReason",
+ },
+ },
+ },
+ },
+ },
+ want: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway1",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionFalse,
+ Reason: "SomeReason",
+ },
+ },
+ },
+ },
+ },
+
+ {
+ name: "nothing changed",
+ args: args{
+ old: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway1",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionFalse,
+ Reason: "SomeReason",
+ },
+ },
+ },
+ },
+ new: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionFalse,
+ Reason: "SomeReason",
+ },
+ },
+ },
+ },
+ },
+ want: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway1",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionFalse,
+ Reason: "SomeReason",
+ },
+ },
+ },
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := mergeRouteParentStatus("default", tt.args.old, tt.args.new); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("mergeRouteParentStatus() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/internal/provider/kubernetes/status_updater.go b/internal/provider/kubernetes/status_updater.go
index 59ff64d3352..1bafe23668b 100644
--- a/internal/provider/kubernetes/status_updater.go
+++ b/internal/provider/kubernetes/status_updater.go
@@ -7,6 +7,7 @@ package kubernetes
import (
"context"
+ "sync"
"time"
"github.com/go-logr/logr"
@@ -23,7 +24,7 @@ import (
gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
- "github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/metrics"
)
@@ -56,17 +57,21 @@ func (m MutatorFunc) Mutate(old client.Object) client.Object {
type UpdateHandler struct {
log logr.Logger
client client.Client
- sendUpdates chan struct{}
updateChannel chan Update
+ wg *sync.WaitGroup
}
func NewUpdateHandler(log logr.Logger, client client.Client) *UpdateHandler {
- return &UpdateHandler{
+ u := &UpdateHandler{
log: log,
client: client,
- sendUpdates: make(chan struct{}),
- updateChannel: make(chan Update, 100),
+ updateChannel: make(chan Update, 1000),
+ wg: new(sync.WaitGroup),
}
+
+ u.wg.Add(1)
+
+ return u
}
func (u *UpdateHandler) apply(update Update) {
@@ -130,7 +135,7 @@ func (u *UpdateHandler) Start(ctx context.Context) error {
defer u.log.Info("stopped status update handler")
// Enable Updaters to start sending updates to this handler.
- close(u.sendUpdates)
+ u.wg.Done()
for {
select {
@@ -148,8 +153,8 @@ func (u *UpdateHandler) Start(ctx context.Context) error {
// Writer retrieves the interface that should be used to write to the UpdateHandler.
func (u *UpdateHandler) Writer() Updater {
return &UpdateWriter{
- enabled: u.sendUpdates,
updateChannel: u.updateChannel,
+ wg: u.wg,
}
}
@@ -160,18 +165,15 @@ type Updater interface {
// UpdateWriter takes status updates and sends these to the UpdateHandler via a channel.
type UpdateWriter struct {
- enabled <-chan struct{}
updateChannel chan<- Update
+ wg *sync.WaitGroup
}
// Send sends the given Update off to the update channel for writing by the UpdateHandler.
func (u *UpdateWriter) Send(update Update) {
- // Non-blocking receive to see if we should pass along update.
- select {
- case <-u.enabled:
- u.updateChannel <- update
- default:
- }
+ // Wait until updater is ready
+ u.wg.Wait()
+ u.updateChannel <- update
}
// isStatusEqual checks if two objects have equivalent status.
@@ -318,35 +320,35 @@ func kindOf(obj interface{}) string {
var kind string
switch o := obj.(type) {
case *gwapiv1.GatewayClass:
- kind = gatewayapi.KindGatewayClass
+ kind = resource.KindGatewayClass
case *gwapiv1.Gateway:
- kind = gatewayapi.KindGateway
+ kind = resource.KindGateway
case *gwapiv1.HTTPRoute:
- kind = gatewayapi.KindHTTPRoute
+ kind = resource.KindHTTPRoute
case *gwapiv1a2.TLSRoute:
- kind = gatewayapi.KindTLSRoute
+ kind = resource.KindTLSRoute
case *gwapiv1a2.TCPRoute:
- kind = gatewayapi.KindTCPRoute
+ kind = resource.KindTCPRoute
case *gwapiv1a2.UDPRoute:
- kind = gatewayapi.KindUDPRoute
+ kind = resource.KindUDPRoute
case *gwapiv1.GRPCRoute:
- kind = gatewayapi.KindGRPCRoute
+ kind = resource.KindGRPCRoute
case *egv1a1.EnvoyPatchPolicy:
- kind = gatewayapi.KindEnvoyPatchPolicy
+ kind = resource.KindEnvoyPatchPolicy
case *egv1a1.ClientTrafficPolicy:
- kind = gatewayapi.KindClientTrafficPolicy
+ kind = resource.KindClientTrafficPolicy
case *egv1a1.BackendTrafficPolicy:
- kind = gatewayapi.KindBackendTrafficPolicy
+ kind = resource.KindBackendTrafficPolicy
case *egv1a1.SecurityPolicy:
- kind = gatewayapi.KindSecurityPolicy
+ kind = resource.KindSecurityPolicy
case *egv1a1.EnvoyExtensionPolicy:
- kind = gatewayapi.KindEnvoyExtensionPolicy
+ kind = resource.KindEnvoyExtensionPolicy
case *gwapiv1a3.BackendTLSPolicy:
- kind = gatewayapi.KindBackendTLSPolicy
+ kind = resource.KindBackendTLSPolicy
case *unstructured.Unstructured:
kind = o.GetKind()
case *egv1a1.Backend:
- kind = egv1a1.KindBackend
+ kind = resource.KindBackend
default:
kind = "Unknown"
}
diff --git a/internal/provider/kubernetes/test/utils.go b/internal/provider/kubernetes/test/utils.go
index ae798b57d77..77bc50c5e6f 100644
--- a/internal/provider/kubernetes/test/utils.go
+++ b/internal/provider/kubernetes/test/utils.go
@@ -12,6 +12,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
+ "sigs.k8s.io/controller-runtime/pkg/client"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
@@ -107,8 +108,8 @@ func GetSecret(nsName types.NamespacedName) *corev1.Secret {
}
// GetHTTPRoute returns a sample HTTPRoute with a parent reference.
-func GetHTTPRoute(nsName types.NamespacedName, parent string, serviceName types.NamespacedName, port int32) *gwapiv1.HTTPRoute {
- return &gwapiv1.HTTPRoute{
+func GetHTTPRoute(nsName types.NamespacedName, parent string, serviceName types.NamespacedName, port int32, httpRouteFilterName string) *gwapiv1.HTTPRoute {
+ httpRoute := &gwapiv1.HTTPRoute{
ObjectMeta: metav1.ObjectMeta{
Namespace: nsName.Namespace,
Name: nsName.Name,
@@ -135,6 +136,21 @@ func GetHTTPRoute(nsName types.NamespacedName, parent string, serviceName types.
},
},
}
+
+ if httpRouteFilterName != "" {
+ httpRoute.Spec.Rules[0].Filters = []gwapiv1.HTTPRouteFilter{
+ {
+ Type: gwapiv1.HTTPRouteFilterExtensionRef,
+ ExtensionRef: &gwapiv1.LocalObjectReference{
+ Group: egv1a1.GroupName,
+ Kind: egv1a1.KindHTTPRouteFilter,
+ Name: gwapiv1.ObjectName(httpRouteFilterName),
+ },
+ },
+ }
+ }
+
+ return httpRoute
}
// GetGRPCRoute returns a sample GRPCRoute with a parent reference.
@@ -256,7 +272,7 @@ func GetUDPRoute(nsName types.NamespacedName, parent string, serviceName types.N
}
// GetGatewayDeployment returns a sample Deployment for a Gateway object.
-func GetGatewayDeployment(nsName types.NamespacedName, labels map[string]string) *appsv1.Deployment {
+func GetGatewayDeployment(nsName types.NamespacedName, labels map[string]string) client.Object {
return &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Namespace: nsName.Namespace,
@@ -283,6 +299,34 @@ func GetGatewayDeployment(nsName types.NamespacedName, labels map[string]string)
}
}
+// GetGatewayDaemonSet returns a sample DaemonSet for a Gateway object.
+func GetGatewayDaemonSet(nsName types.NamespacedName, labels map[string]string) client.Object {
+ return &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: nsName.Namespace,
+ Name: nsName.Name,
+ Labels: labels,
+ },
+ Spec: appsv1.DaemonSetSpec{
+ Selector: &metav1.LabelSelector{MatchLabels: labels},
+ Template: corev1.PodTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: labels,
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{{
+ Name: "dummy",
+ Image: "dummy",
+ Ports: []corev1.ContainerPort{{
+ ContainerPort: 8080,
+ }},
+ }},
+ },
+ },
+ },
+ }
+}
+
// GetService returns a sample Service with labels and ports.
func GetService(nsName types.NamespacedName, labels map[string]string, ports map[string]int32) *corev1.Service {
service := &corev1.Service{
@@ -329,3 +373,24 @@ func GetEndpointSlice(nsName types.NamespacedName, svcName string) *discoveryv1.
},
}
}
+
+// GetHTTPRouteFilter returns a sample Service with labels and ports.
+func GetHTTPRouteFilter(nsName types.NamespacedName) *egv1a1.HTTPRouteFilter {
+ return &egv1a1.HTTPRouteFilter{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: nsName.Name,
+ Namespace: nsName.Namespace,
+ },
+ Spec: egv1a1.HTTPRouteFilterSpec{
+ URLRewrite: &egv1a1.HTTPURLRewriteFilter{
+ Path: &egv1a1.HTTPPathModifier{
+ Type: egv1a1.RegexHTTPPathModifier,
+ ReplaceRegexMatch: &egv1a1.ReplaceRegexMatch{
+ Pattern: "foo",
+ Substitution: "bar",
+ },
+ },
+ },
+ },
+ }
+}
diff --git a/internal/provider/resource_provider.go b/internal/provider/resource_provider.go
new file mode 100644
index 00000000000..d14f95d158d
--- /dev/null
+++ b/internal/provider/resource_provider.go
@@ -0,0 +1,20 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package provider
+
+import (
+ "context"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+)
+
+type Provider interface {
+ // Start starts the resource provider.
+ Start(ctx context.Context) error
+
+ // Type returns the type of resource provider.
+ Type() egv1a1.ProviderType
+}
diff --git a/internal/provider/runner/runner.go b/internal/provider/runner/runner.go
index 32f5a30fe8c..94488489376 100644
--- a/internal/provider/runner/runner.go
+++ b/internal/provider/runner/runner.go
@@ -14,6 +14,8 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/message"
+ "github.com/envoyproxy/gateway/internal/provider"
+ "github.com/envoyproxy/gateway/internal/provider/file"
"github.com/envoyproxy/gateway/internal/provider/kubernetes"
)
@@ -37,24 +39,61 @@ func (r *Runner) Name() string {
// Start the provider runner
func (r *Runner) Start(ctx context.Context) (err error) {
r.Logger = r.Logger.WithName(r.Name()).WithValues("runner", r.Name())
- if r.EnvoyGateway.Provider.Type == egv1a1.ProviderTypeKubernetes {
- r.Logger.Info("Using provider", "type", egv1a1.ProviderTypeKubernetes)
- cfg, err := ctrl.GetConfig()
+
+ var p provider.Provider
+ switch r.EnvoyGateway.Provider.Type {
+ case egv1a1.ProviderTypeKubernetes:
+ p, err = r.createKubernetesProvider()
if err != nil {
- return fmt.Errorf("failed to get kubeconfig: %w", err)
+ return fmt.Errorf("failed to create kubernetes provider: %w", err)
}
- p, err := kubernetes.New(cfg, &r.Config.Server, r.ProviderResources)
+
+ case egv1a1.ProviderTypeCustom:
+ p, err = r.createCustomResourceProvider()
if err != nil {
- return fmt.Errorf("failed to create provider %s: %w", egv1a1.ProviderTypeKubernetes, err)
+ return fmt.Errorf("failed to create custom provider: %w", err)
+ }
+
+ default:
+ // Unsupported provider.
+ return fmt.Errorf("unsupported provider type %v", r.EnvoyGateway.Provider.Type)
+ }
+
+ r.Logger.Info("Running provider", "type", p.Type())
+ go func() {
+ if err = p.Start(ctx); err != nil {
+ r.Logger.Error(err, "unable to start provider")
}
- go func() {
- err := p.Start(ctx)
- if err != nil {
- r.Logger.Error(err, "unable to start provider")
- }
- }()
- return nil
+ }()
+
+ return nil
+}
+
+func (r *Runner) createKubernetesProvider() (*kubernetes.Provider, error) {
+ cfg, err := ctrl.GetConfig()
+ if err != nil {
+ return nil, fmt.Errorf("failed to get kubeconfig: %w", err)
}
- // Unsupported provider.
- return fmt.Errorf("unsupported provider type %v", r.EnvoyGateway.Provider.Type)
+
+ p, err := kubernetes.New(cfg, &r.Config.Server, r.ProviderResources)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create provider %s: %w", egv1a1.ProviderTypeKubernetes, err)
+ }
+
+ return p, err
+}
+
+func (r *Runner) createCustomResourceProvider() (p provider.Provider, err error) {
+ switch r.EnvoyGateway.Provider.Custom.Resource.Type {
+ case egv1a1.ResourceProviderTypeFile:
+ p, err = file.New(&r.Config.Server, r.ProviderResources)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create provider %s: %w", egv1a1.ProviderTypeCustom, err)
+ }
+
+ default:
+ return nil, fmt.Errorf("unsupported resource provider type")
+ }
+
+ return
}
diff --git a/internal/provider/runner/runner_test.go b/internal/provider/runner/runner_test.go
deleted file mode 100644
index a393462da94..00000000000
--- a/internal/provider/runner/runner_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright Envoy Gateway Authors
-// SPDX-License-Identifier: Apache-2.0
-// The full text of the Apache license is available in the LICENSE file at
-// the root of the repo.
-
-package runner
-
-import (
- "context"
- "testing"
-
- "github.com/stretchr/testify/require"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
- egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
- "github.com/envoyproxy/gateway/internal/envoygateway/config"
- "github.com/envoyproxy/gateway/internal/logging"
- "github.com/envoyproxy/gateway/internal/message"
-)
-
-func TestStart(t *testing.T) {
- logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
-
- testCases := []struct {
- name string
- cfg *config.Server
- expect bool
- }{
- {
- name: "file provider",
- cfg: &config.Server{
- EnvoyGateway: &egv1a1.EnvoyGateway{
- TypeMeta: metav1.TypeMeta{
- APIVersion: egv1a1.GroupVersion.String(),
- Kind: egv1a1.KindEnvoyGateway,
- },
- EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
- Provider: &egv1a1.EnvoyGatewayProvider{
- Type: egv1a1.ProviderTypeFile,
- },
- },
- },
- Logger: logger,
- },
- expect: false,
- },
- }
-
- for _, tc := range testCases {
- tc := tc
- t.Run(tc.name, func(t *testing.T) {
- runner := &Runner{
- Config: Config{
- Server: *tc.cfg,
- ProviderResources: new(message.ProviderResources),
- },
- }
- ctx, cancel := context.WithCancel(context.Background())
- t.Cleanup(cancel)
- err := runner.Start(ctx)
- if tc.expect {
- require.NoError(t, err)
- } else {
- require.Error(t, err, "An error was expected")
- }
- })
- }
-}
diff --git a/internal/troubleshoot/collect/config_dump.go b/internal/troubleshoot/collect/config_dump.go
index fe9ff9558ad..7a5c9b38343 100644
--- a/internal/troubleshoot/collect/config_dump.go
+++ b/internal/troubleshoot/collect/config_dump.go
@@ -96,5 +96,5 @@ func configDump(cli kube.CLIClient, nn types.NamespacedName, includeEds bool) ([
if includeEds {
reqPath = fmt.Sprintf("%s?include_eds", reqPath)
}
- return requestWithPortForwarder(cli, nn, 19000, reqPath)
+ return RequestWithPortForwarder(cli, nn, 19000, reqPath)
}
diff --git a/internal/troubleshoot/collect/prometheus_metrics.go b/internal/troubleshoot/collect/prometheus_metrics.go
index 785b99719af..9f659a54a22 100644
--- a/internal/troubleshoot/collect/prometheus_metrics.go
+++ b/internal/troubleshoot/collect/prometheus_metrics.go
@@ -94,7 +94,7 @@ func (p PrometheusMetric) Collect(_ chan<- interface{}) (tbcollect.CollectorResu
reqPath = v
}
- data, err := requestWithPortForwarder(cliClient, nn, port, reqPath)
+ data, err := RequestWithPortForwarder(cliClient, nn, port, reqPath)
if err != nil {
logs = append(logs, fmt.Sprintf("pod %s/%s is skipped because of err: %v", pod.Namespace, pod.Name, err))
continue
@@ -121,7 +121,7 @@ func listPods(ctx context.Context, client kubernetes.Interface, namespace string
return pods.Items, nil
}
-func requestWithPortForwarder(cli kube.CLIClient, nn types.NamespacedName, port int, reqPath string) ([]byte, error) {
+func RequestWithPortForwarder(cli kube.CLIClient, nn types.NamespacedName, port int, reqPath string) ([]byte, error) {
fw, err := kube.NewLocalPortForwarder(cli, nn, 0, port)
if err != nil {
return nil, err
diff --git a/internal/utils/file/file.go b/internal/utils/file/file.go
index 51a02571493..da4cb67a877 100644
--- a/internal/utils/file/file.go
+++ b/internal/utils/file/file.go
@@ -8,8 +8,10 @@ package file
import (
"bufio"
"os"
+ "path/filepath"
)
+// Write writes data into a given filepath.
func Write(data string, filepath string) error {
file, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil {
@@ -25,3 +27,13 @@ func Write(data string, filepath string) error {
return nil
}
+
+// WriteDir write data into a given filename under certain directory.
+func WriteDir(data []byte, dir, filename string) error {
+ err := os.MkdirAll(dir, 0o755)
+ if err != nil {
+ return err
+ }
+
+ return Write(string(data), filepath.Join(dir, filename))
+}
diff --git a/internal/utils/file/file_test.go b/internal/utils/file/file_test.go
new file mode 100644
index 00000000000..488ff415191
--- /dev/null
+++ b/internal/utils/file/file_test.go
@@ -0,0 +1,28 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package file
+
+import (
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestWriteDir(t *testing.T) {
+ tmpDir := t.TempDir()
+ testFilename := "test"
+ data := []byte("foobar")
+
+ err := WriteDir(data, tmpDir, testFilename)
+ require.NoError(t, err)
+ require.FileExists(t, filepath.Join(tmpDir, testFilename))
+
+ got, err := os.ReadFile(filepath.Join(tmpDir, testFilename))
+ require.NoError(t, err)
+ require.Equal(t, data, got)
+}
diff --git a/internal/utils/jsonpatch/jsonpathtopointer.go b/internal/utils/jsonpatch/jsonpathtopointer.go
new file mode 100644
index 00000000000..18bfb569335
--- /dev/null
+++ b/internal/utils/jsonpatch/jsonpathtopointer.go
@@ -0,0 +1,134 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package jsonpatch
+
+import (
+ "reflect"
+ "strings"
+
+ "github.com/ohler55/ojg/jp"
+ "github.com/ohler55/ojg/oj"
+ "github.com/pkg/errors"
+)
+
+func ConvertPathToPointers(jsonDoc []byte, jsonPath string, path string) ([]string, error) {
+ var jsonPointers []string
+
+ jObj, err := oj.Parse(jsonDoc)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error during parsing json")
+ }
+
+ jPath, err := jp.ParseString(jsonPath)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error during parsing jpath")
+ }
+
+ if len(jPath) == 1 {
+ _, isRoot := jPath[0].(jp.Root)
+ if isRoot {
+ return nil, errors.New("Using only Root ('$') in json path expression is not allowed!")
+ }
+ }
+
+ locations := jPath.Locate(jObj, 0)
+ for _, l := range locations {
+ jsonPointer, err := expToPointer(l)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error during converting path to pointer")
+ }
+ jsonPointers = append(jsonPointers, concat(jsonPointer, path))
+ }
+ return jsonPointers, nil
+}
+
+func concat(jsonPointer string, path string) string {
+ if path == "" {
+ return jsonPointer
+ }
+ const separator string = "/"
+ parts := []string{
+ strings.TrimSuffix(jsonPointer, separator),
+ strings.TrimPrefix(path, separator),
+ }
+ return strings.Join(parts, separator)
+}
+
+func expToPointer(e jp.Expr) (string, error) {
+ var buf []byte
+ for _, f := range e {
+ v, err := fragToPointer(f)
+ if err != nil {
+ return "", err
+ }
+ if v != nil {
+ buf = append(buf, '/')
+ }
+
+ buf = append(buf, v...)
+ }
+
+ return string(buf), nil
+}
+
+func fragToPointer(f jp.Frag) ([]byte, error) {
+ switch v := f.(type) {
+ case jp.Root:
+ return rootToPointer()
+ case jp.Nth:
+ return nthToPointer(v)
+ case jp.Child:
+ return toPointer(v)
+ default:
+ return nil, errors.New("There is no conversion implemented for " + reflect.TypeOf(v).Name())
+ }
+}
+
+func rootToPointer() ([]byte, error) {
+ return nil, nil
+}
+
+func nthToPointer(f jp.Nth) ([]byte, error) {
+ var buf []byte
+ i := int(f)
+ if i < 0 {
+ buf = append(buf, '-')
+ i = -i
+ }
+ num := [20]byte{}
+ cnt := 0
+ for ; i != 0; cnt++ {
+ num[cnt] = byte(i%10) + '0'
+ i /= 10
+ }
+ if 0 < cnt {
+ cnt--
+ for ; 0 <= cnt; cnt-- {
+ buf = append(buf, num[cnt])
+ }
+ } else {
+ buf = append(buf, '0')
+ }
+ return buf, nil
+}
+
+func toPointer(f jp.Child) ([]byte, error) {
+ var buf []byte
+
+ // JSONPointer escaping https://datatracker.ietf.org/doc/html/rfc6901#section-3
+ for _, b := range []byte(string(f)) {
+ switch b {
+ case '~':
+ buf = append(buf, "~0"...)
+ case '/':
+ buf = append(buf, "~1"...)
+ default:
+ buf = append(buf, b)
+ }
+ }
+
+ return buf, nil
+}
diff --git a/internal/utils/jsonpatch/jsonpathtopointer_test.go b/internal/utils/jsonpatch/jsonpathtopointer_test.go
new file mode 100644
index 00000000000..03bc25dd8c4
--- /dev/null
+++ b/internal/utils/jsonpatch/jsonpathtopointer_test.go
@@ -0,0 +1,500 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package jsonpatch
+
+import (
+ "sort"
+ "testing"
+
+ "github.com/ohler55/ojg/jp"
+ "github.com/stretchr/testify/require"
+)
+
+const case1Simple string = `{
+ "a": "b"
+ }`
+
+const case2Nested string = `{
+ "a": "b",
+ "v": [{
+ "x": "test1",
+ "y": "hello"
+ },
+ {
+ "x": "test2",
+ "y": "world"
+ }],
+ "f":{
+ "w": "hi",
+ "q": "welcome",
+ "y": "ciao"
+ },
+ "y": "c"
+ }`
+
+const case3Route string = `{
+ "name": "default/eg/http",
+ "virtual_hosts": [
+ {
+ "name": "default/eg/http/www_test_com",
+ "domains": [
+ "www.test.com"
+ ],
+ "routes": [
+ {
+ "name": "httproute/default/backend/rule/0/match/0/www_test_com",
+ "match": {
+ "prefix": "/"
+ },
+ "route": {
+ "cluster": "httproute/default/backend/rule/0",
+ "upgrade_configs": [
+ {
+ "upgrade_type": "websocket"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "default/eg/http/www_example_com",
+ "domains": [
+ "www.example.com"
+ ],
+ "routes": [
+ {
+ "name": "httproute/default/backend/rule/1/match/1/www_example_com",
+ "match": {
+ "prefix": "/"
+ },
+ "route": {
+ "cluster": "httproute/default/backend/rule/1",
+ "upgrade_configs": [
+ {
+ "upgrade_type": "websocket"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ],
+ "ignore_port_in_host_matching": true
+}`
+
+const case4Escaping string = `{
+ "values": [{
+ "name": "test1",
+ "dotted.key": "Hello"
+ },
+ {
+ "name": "test2",
+ "dotted.key": "there"
+ },
+ {
+ "name": "test3",
+ "~abc": "tilde"
+ },
+ {
+ "name": "test4",
+ "//abc": "slash"
+ },
+ {
+ "name": "test5",
+ "~/abc/~": "mixed"
+ }]
+}`
+
+func Test(t *testing.T) {
+ testCases := []struct {
+ name string
+
+ // Json Document
+ doc string
+
+ // JSONPath
+ jsonPath string
+
+ // path
+ path string
+
+ // List of expected pointers
+ expected []string
+ }{
+ {
+ name: "TestCase-01",
+ doc: case1Simple,
+ jsonPath: "$.xyz",
+ expected: []string{},
+ },
+ {
+ name: "TestCase-02",
+ doc: case1Simple,
+ jsonPath: "$.xyz",
+ path: "doesnotexist",
+ expected: []string{},
+ },
+ {
+ name: "TestCase-03",
+ doc: case1Simple,
+ jsonPath: "$.a",
+ expected: []string{
+ "/a",
+ },
+ },
+ {
+ name: "TestCase-04",
+ doc: case2Nested,
+ jsonPath: "$.v[?(@.x=='test2')]",
+ expected: []string{
+ "/v/1",
+ },
+ },
+ {
+ name: "TestCase-05",
+ doc: case2Nested,
+ jsonPath: "..v[?(@.x=='test1')].y",
+ expected: []string{
+ "/v/0/y",
+ },
+ },
+ {
+ name: "TestCase-06",
+ doc: case2Nested,
+ jsonPath: "$.v[?(@.x=='test2')].y",
+ expected: []string{
+ "/v/1/y",
+ },
+ },
+ {
+ name: "TestCase-07",
+ doc: case2Nested,
+ jsonPath: "$.v[?(@.x=='test1')].y",
+ expected: []string{
+ "/v/0/y",
+ },
+ },
+ {
+ name: "TestCase-08",
+ doc: case2Nested,
+ jsonPath: "$.v[*].y",
+ expected: []string{
+ "/v/0/y",
+ "/v/1/y",
+ },
+ },
+ {
+ name: "TestCase-09",
+ doc: case2Nested,
+ jsonPath: "$.v[?(@.x=='UNKNOWN')].y",
+ expected: []string{},
+ },
+ {
+ name: "TestCase-10",
+ doc: case1Simple,
+ jsonPath: ".a",
+ expected: []string{
+ "/a",
+ },
+ },
+ {
+ name: "TestCase-11",
+ doc: case1Simple,
+ jsonPath: "a",
+ expected: []string{
+ "/a",
+ },
+ },
+ {
+ name: "TestCase-12",
+ doc: case2Nested,
+ jsonPath: "f.w",
+ expected: []string{
+ "/f/w",
+ },
+ },
+ {
+ name: "TestCase-13",
+ doc: case2Nested,
+ jsonPath: "f.*",
+ expected: []string{
+ "/f/w",
+ "/f/q",
+ "/f/y",
+ },
+ },
+ {
+ name: "TestCase-14",
+ doc: case2Nested,
+ jsonPath: "v.*",
+ expected: []string{
+ "/v/0",
+ "/v/1",
+ },
+ },
+ {
+ name: "TestCase-15",
+ doc: case2Nested,
+ jsonPath: "v.**",
+ expected: []string{
+ "/v/0/x",
+ "/v/0/y",
+ "/v/1/x",
+ "/v/1/y",
+ },
+ },
+ {
+ name: "TestCase-16",
+ doc: case2Nested,
+ jsonPath: "$..y",
+ expected: []string{
+ "/f/y",
+ "/v/0/y",
+ "/v/1/y",
+ "/y",
+ },
+ },
+ {
+ name: "TestCase-17",
+ doc: case2Nested,
+ jsonPath: "..y",
+ expected: []string{
+ "/f/y",
+ "/v/0/y",
+ "/v/1/y",
+ "/y",
+ },
+ },
+ {
+ name: "TestCase-18",
+ doc: case2Nested,
+ jsonPath: "**.y",
+ expected: []string{
+ "/v/0/y",
+ "/v/1/y",
+ },
+ },
+ {
+ name: "TestCase-19",
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www_example_com')]",
+ expected: []string{
+ "/virtual_hosts/1/routes/0",
+ },
+ },
+ {
+ name: "TestCase-20",
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www_test_com')]",
+ expected: []string{
+ "/virtual_hosts/0/routes/0",
+ },
+ },
+ {
+ name: "TestCase-21",
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')]",
+ expected: []string{
+ "/virtual_hosts/0/routes/0",
+ "/virtual_hosts/1/routes/0",
+ },
+ },
+ {
+ name: "TestCase-22",
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')].route.cluster",
+ expected: []string{
+ "/virtual_hosts/0/routes/0/route/cluster",
+ "/virtual_hosts/1/routes/0/route/cluster",
+ },
+ },
+ {
+ name: "TestCase-23",
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')]['route']['cluster']",
+ expected: []string{
+ "/virtual_hosts/0/routes/0/route/cluster",
+ "/virtual_hosts/1/routes/0/route/cluster",
+ },
+ },
+ {
+ name: "TestCase-24",
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name=='httproute/default/backend/rule/1/match/1/www_example_com')].route.upgrade_configs",
+ expected: []string{
+ "/virtual_hosts/1/routes/0/route/upgrade_configs",
+ },
+ },
+ {
+ name: "TestCase-25",
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')]",
+ path: "/abc",
+ expected: []string{
+ "/virtual_hosts/0/routes/0/abc",
+ "/virtual_hosts/1/routes/0/abc",
+ },
+ },
+ {
+ name: "TestCase-26",
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')]",
+ path: "abc",
+ expected: []string{
+ "/virtual_hosts/0/routes/0/abc",
+ "/virtual_hosts/1/routes/0/abc",
+ },
+ },
+ {
+ name: "TestCase-27",
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')]",
+ path: "/",
+ expected: []string{
+ "/virtual_hosts/0/routes/0/",
+ "/virtual_hosts/1/routes/0/",
+ },
+ },
+ {
+ name: "TestCase-28",
+ doc: case4Escaping,
+ jsonPath: "$.values[?(@.name =~ 'test2')]",
+ path: "dotted.key",
+ expected: []string{
+ "/values/1/dotted.key",
+ },
+ },
+ {
+ name: "TestCase-29",
+ doc: case4Escaping,
+ jsonPath: "$.values[?(@.name =~ 'test2')]['dotted.key']",
+ expected: []string{
+ "/values/1/dotted.key",
+ },
+ },
+ {
+ name: "TestCase-30",
+ doc: case4Escaping,
+ jsonPath: "$.values[?(@.name =~ 'test3')].~abc",
+ expected: []string{
+ "/values/2/~0abc",
+ },
+ },
+ {
+ name: "TestCase-31",
+ doc: case4Escaping,
+ jsonPath: "$.values[?(@.name =~ 'test4')]['//abc']",
+ expected: []string{
+ "/values/3/~1~1abc",
+ },
+ },
+ {
+ name: "TestCase-32",
+ doc: case4Escaping,
+ jsonPath: "$.values[?(@.name =~ 'test5')]['~/abc/~']",
+ expected: []string{
+ "/values/4/~0~1abc~1~0",
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ pointers, err := ConvertPathToPointers([]byte(tc.doc), tc.jsonPath, tc.path)
+ if err != nil {
+ require.NoError(t, err)
+ }
+
+ expectedAsString := asString(tc.expected)
+ pointersAsString := asString(pointers)
+
+ require.Equal(t, expectedAsString, pointersAsString)
+ })
+ }
+}
+
+func TestException(t *testing.T) {
+ tests := []struct {
+ name string
+
+ // Json Document
+ doc string
+
+ // JSONPath
+ jsonPath string
+
+ // path
+ path string
+
+ // expected exception
+ expected string
+ }{
+ {
+ name: "TestCaseEx-01",
+ doc: case1Simple,
+ jsonPath: ".$",
+ expected: "Error during parsing jpath",
+ },
+ {
+ name: "TestCaseEx-02",
+ doc: case1Simple,
+ jsonPath: "$",
+ expected: "only Root",
+ },
+ {
+ name: "TestCaseEx-03",
+ doc: "{",
+ jsonPath: ".$",
+ expected: "Error during parsing json",
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ _, err := ConvertPathToPointers([]byte(test.doc), test.jsonPath, test.path)
+ if err == nil {
+ require.Error(t, err)
+ }
+ require.ErrorContains(t, err, test.expected)
+ })
+ }
+}
+
+func TestUnexpectedFrag(t *testing.T) {
+ expr := jp.Expr{}
+ expr = append(expr, jp.Union{})
+
+ _, err := expToPointer(expr)
+ if err == nil {
+ t.Error("Error expected, but no error found!")
+ }
+
+ require.ErrorContains(t, err, "There is no conversion implemented for Union")
+}
+
+func TestNegativeNth(t *testing.T) {
+ result, err := nthToPointer(jp.Nth(-1))
+ if err != nil {
+ t.Error(err)
+ }
+ test := string(result)
+ if test != "-1" {
+ t.Error("expected -1, but was " + test + "!")
+ }
+}
+
+func asString(values []string) string {
+ var buf []byte
+
+ sort.Strings(values)
+ for _, v := range values {
+ buf = append(buf, []byte(v)...)
+ buf = append(buf, []byte("\n")...)
+ }
+
+ return string(buf)
+}
diff --git a/internal/utils/jsonpatch/patch.go b/internal/utils/jsonpatch/patch.go
new file mode 100644
index 00000000000..8c14ae19f46
--- /dev/null
+++ b/internal/utils/jsonpatch/patch.go
@@ -0,0 +1,99 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package jsonpatch
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+
+ jsonpatchv5 "github.com/evanphx/json-patch/v5"
+ "sigs.k8s.io/yaml"
+
+ "github.com/envoyproxy/gateway/internal/ir"
+)
+
+// ApplyJSONPatches applies a series of JSONPatches to a provided JSON document.
+// Patches are applied in order, and any errors are aggregated into the return value.
+// An error with a specific patch just means that this specific patch is skipped, the document
+// will still be modified with any other provided patch operation.
+// If a patch is applied to a JSONPath, then that JSONPath is first exploded to standard paths
+// and the patch is applied to all matching paths.
+func ApplyJSONPatches(document json.RawMessage, patches ...ir.JSONPatchOperation) (json.RawMessage, error) {
+ opts := jsonpatchv5.NewApplyOptions()
+ opts.EnsurePathExistsOnAdd = true
+
+ var tErrs, err error
+ for _, p := range patches {
+
+ if err := p.Validate(); err != nil {
+ tErrs = errors.Join(tErrs, err)
+ continue
+ }
+
+ var jsonPointers []string
+ if p.JSONPath != nil {
+ path := ""
+ if p.Path != nil {
+ path = *p.Path
+ }
+ jsonPointers, err = ConvertPathToPointers(document, *p.JSONPath, path)
+ if err != nil {
+ tErr := fmt.Errorf("unable to convert jsonPath: '%s' into jsonPointers, err: %s", *p.JSONPath, err.Error())
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if len(jsonPointers) == 0 {
+ tErr := fmt.Errorf("no jsonPointers were found while evaluating the jsonPath: '%s'. "+
+ "Ensure the elements you are trying to select with the jsonPath exist in the document. "+
+ "If you need to add a non-existing property, use the 'path' attribute", *p.JSONPath)
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ } else {
+ jsonPointers = []string{*p.Path}
+ }
+
+ for _, path := range jsonPointers {
+ op := ir.JSONPatchOperation{
+ Path: &path,
+ Op: p.Op,
+ Value: p.Value,
+ From: p.From,
+ }
+
+ // Convert patch to JSON
+ // The patch library expects an array so convert it into one
+ y, err := yaml.Marshal([]ir.JSONPatchOperation{op})
+ if err != nil {
+ tErr := fmt.Errorf("unable to marshal patch %+v, err: %s", op, err.Error())
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ jsonBytes, err := yaml.YAMLToJSON(y)
+ if err != nil {
+ tErr := fmt.Errorf("unable to convert patch to json %s, err: %s", string(y), err.Error())
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ patchObj, err := jsonpatchv5.DecodePatch(jsonBytes)
+ if err != nil {
+ tErr := fmt.Errorf("unable to decode patch %s, err: %s", string(jsonBytes), err.Error())
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+
+ // Apply patch
+ document, err = patchObj.ApplyWithOptions(document, opts)
+ if err != nil {
+ tErr := fmt.Errorf("unable to apply patch:\n%s on resource:\n%s, err: %s", string(jsonBytes), string(document), err.Error())
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ }
+ }
+ return document, tErrs
+}
diff --git a/internal/utils/jsonpatch/patch_test.go b/internal/utils/jsonpatch/patch_test.go
new file mode 100644
index 00000000000..cfd4ec8e2e4
--- /dev/null
+++ b/internal/utils/jsonpatch/patch_test.go
@@ -0,0 +1,263 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package jsonpatch
+
+import (
+ "encoding/json"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+ "k8s.io/utils/ptr"
+
+ "github.com/envoyproxy/gateway/internal/ir"
+)
+
+const sourceDocument = `
+{
+ "topLevel" : {
+ "mapContainer" : {
+ "key": "value",
+ "other": "key"
+ },
+ "arrayContainer": [
+ "str1",
+ "str2"
+ ],
+ "mapArray" : [
+ {
+ "name": "first",
+ "key" : "value"
+ },
+ {
+ "name": "second",
+ "key" : "other value"
+ }
+ ]
+ }
+}
+`
+
+const sourceDotEscape = `
+ {
+ "otherLevel": {
+ "dot.key": "oldValue",
+ "~my": "file",
+ "/other/": "zip"
+ }
+ }
+`
+
+var expectedDotEscapeCase1 = `{
+ "otherLevel": {
+ "dot.key": "newValue",
+ "~my": "file",
+ "/other/": "zip"
+ }
+}`
+
+var expectedDotEscapeCase2 = `{
+ "otherLevel": {
+ "dot.key": "oldValue",
+ "~my": "folder",
+ "/other/": "tar"
+ }
+}`
+
+func TestApplyJSONPatches(t *testing.T) {
+ testCases := []struct {
+ doc string
+ name string
+ patchOperation []ir.JSONPatchOperation
+ errorExpected bool
+ errorContains *string
+ expectedDoc *string
+ }{
+ {
+ name: "simple add with single patch",
+ doc: sourceDocument,
+ patchOperation: []ir.JSONPatchOperation{
+ {
+ Op: "add",
+ Path: ptr.To("/topLevel/newKey"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte("true"),
+ },
+ },
+ },
+ errorExpected: false,
+ },
+ {
+ name: "two operations in a set",
+ doc: sourceDocument,
+ patchOperation: []ir.JSONPatchOperation{
+ {
+ Op: "add",
+ Path: ptr.To("/topLevel/newKey"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte("true"),
+ },
+ },
+ {
+ Op: "remove",
+ Path: ptr.To("/topLevel/arrayContainer/1"),
+ },
+ },
+ errorExpected: false,
+ },
+ {
+ name: "invalid operation",
+ doc: sourceDocument,
+ patchOperation: []ir.JSONPatchOperation{
+ {
+ Op: "badbadbad",
+ Path: ptr.To("/topLevel/newKey"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte("true"),
+ },
+ },
+ },
+ errorExpected: true,
+ errorContains: ptr.To("unsupported JSONPatch operation"),
+ },
+ {
+ name: "jsonpath affecting two places",
+ doc: sourceDocument,
+ patchOperation: []ir.JSONPatchOperation{
+ {
+ Op: "remove",
+ JSONPath: ptr.To("$.topLevel.mapArray[*].key"),
+ },
+ },
+ errorExpected: false,
+ },
+ {
+ name: "invalid jsonpath",
+ doc: sourceDocument,
+ patchOperation: []ir.JSONPatchOperation{
+ {
+ Op: "remove",
+ JSONPath: ptr.To("i'm not a json path string"),
+ },
+ },
+ errorExpected: true,
+ errorContains: ptr.To("unable to convert jsonPath"),
+ },
+ {
+ name: "dot escaped json path",
+ doc: sourceDotEscape,
+ patchOperation: []ir.JSONPatchOperation{
+ {
+ Op: "replace",
+ JSONPath: ptr.To("$.otherLevel['dot.key']"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte("\"newValue\""),
+ },
+ },
+ },
+ expectedDoc: &expectedDotEscapeCase1,
+ errorExpected: false,
+ },
+ {
+ name: "dot escaped json path combined with path",
+ doc: sourceDotEscape,
+ patchOperation: []ir.JSONPatchOperation{
+ {
+ Op: "replace",
+ Path: ptr.To("dot.key"),
+ JSONPath: ptr.To("$.otherLevel"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte("\"newValue\""),
+ },
+ },
+ },
+ expectedDoc: &expectedDotEscapeCase1,
+ errorExpected: false,
+ },
+ {
+ name: "json pointer chars which need to be escaped",
+ doc: sourceDotEscape,
+ patchOperation: []ir.JSONPatchOperation{
+ {
+ Op: "replace",
+ JSONPath: ptr.To("$.otherLevel['~my']"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte("\"folder\""),
+ },
+ },
+ {
+ Op: "replace",
+ JSONPath: ptr.To("$.otherLevel['/other/']"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte("\"tar\""),
+ },
+ },
+ },
+ expectedDoc: &expectedDotEscapeCase2,
+ errorExpected: false,
+ },
+ {
+ name: "jsonPath returns no jsonPointer",
+ doc: sourceDocument,
+ patchOperation: []ir.JSONPatchOperation{
+ {
+ Op: "replace",
+ JSONPath: ptr.To("$.secondLevel.doesNotExist"),
+ Value: &apiextensionsv1.JSON{
+ Raw: []byte("\"folder\""),
+ },
+ },
+ },
+ errorExpected: true,
+ errorContains: ptr.To("no jsonPointers were found"),
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ jDoc, err := ApplyJSONPatches([]byte(tc.doc), tc.patchOperation...)
+ if tc.errorExpected {
+ require.Error(t, err)
+ if tc.errorContains != nil {
+ require.ErrorContains(t, err, *tc.errorContains)
+ }
+ } else {
+ if tc.expectedDoc != nil {
+ resultData, err := jDoc.MarshalJSON()
+ if err != nil {
+ t.Error(err)
+ }
+
+ resultJSON, err := formatJSON(resultData)
+ if err != nil {
+ t.Error(err)
+ }
+
+ expectedJSON, err := formatJSON([]byte(*tc.expectedDoc))
+ if err != nil {
+ t.Error(err)
+ }
+
+ require.JSONEq(t, expectedJSON, resultJSON)
+ }
+ require.NoError(t, err)
+ }
+ })
+ }
+}
+
+func formatJSON(s []byte) (string, error) {
+ var obj map[string]interface{}
+ err := json.Unmarshal(s, &obj)
+ if err != nil {
+ return "", err
+ }
+ buf, err := json.MarshalIndent(obj, "", " ")
+ if err != nil {
+ return "", err
+ }
+ return string(buf), nil
+}
diff --git a/internal/utils/misc_test.go b/internal/utils/misc_test.go
index 5955f28aecd..f1b10bcec63 100644
--- a/internal/utils/misc_test.go
+++ b/internal/utils/misc_test.go
@@ -24,7 +24,6 @@ func TestGetHashedName(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
result := GetHashedName(tc.nsName, tc.length)
require.Equal(t, tc.expected, result, "Result does not match expected string")
diff --git a/internal/utils/net/ip.go b/internal/utils/net/ip.go
new file mode 100644
index 00000000000..042a655417e
--- /dev/null
+++ b/internal/utils/net/ip.go
@@ -0,0 +1,11 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package net
+
+const (
+ IPv4ListenerAddress = "0.0.0.0"
+ IPv6ListenerAddress = "::"
+)
diff --git a/internal/utils/path/path.go b/internal/utils/path/path.go
new file mode 100644
index 00000000000..5a0793eff1e
--- /dev/null
+++ b/internal/utils/path/path.go
@@ -0,0 +1,67 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package path
+
+import (
+ "os"
+ "path/filepath"
+
+ "k8s.io/apimachinery/pkg/util/sets"
+)
+
+// ValidateOutputPath takes an output file path and returns it as an absolute path.
+// It returns an error if the absolute path cannot be determined or if the parent directory does not exist.
+func ValidateOutputPath(outputPath string) (string, error) {
+ outputPath, err := filepath.Abs(outputPath)
+ if err != nil {
+ return "", err
+ }
+ if _, err := os.Stat(filepath.Dir(outputPath)); err != nil {
+ return "", err
+ }
+ return outputPath, nil
+}
+
+// ListDirsAndFiles return a list of directories and files from a list of paths recursively.
+func ListDirsAndFiles(paths []string) (dirs sets.Set[string], files sets.Set[string]) {
+ dirs, files = sets.New[string](), sets.New[string]()
+ // Separate paths by whether is a directory or not.
+ paths = sets.NewString(paths...).UnsortedList()
+ for _, path := range paths {
+ var p os.FileInfo
+ p, err := os.Lstat(path)
+ if err != nil {
+ // skip
+ continue
+ }
+
+ if p.IsDir() {
+ dirs.Insert(path)
+ } else {
+ files.Insert(path)
+ }
+ }
+
+ // Ignore filepath if its parent directory is also be watched.
+ var ignoreFiles []string
+ for fp := range files {
+ if dirs.Has(filepath.Dir(fp)) {
+ ignoreFiles = append(ignoreFiles, fp)
+ }
+ }
+ files.Delete(ignoreFiles...)
+
+ return
+}
+
+// GetParentDirs returns all the parent directories of given files.
+func GetParentDirs(files []string) sets.Set[string] {
+ parents := sets.New[string]()
+ for _, f := range files {
+ parents.Insert(filepath.Dir(f))
+ }
+ return parents
+}
diff --git a/internal/utils/path/path_test.go b/internal/utils/path/path_test.go
new file mode 100644
index 00000000000..8d1883ea336
--- /dev/null
+++ b/internal/utils/path/path_test.go
@@ -0,0 +1,125 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package path
+
+import (
+ "os"
+ "path"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestListDirsAndFiles(t *testing.T) {
+ basePath, _ := os.MkdirTemp(os.TempDir(), "list-test")
+ defer func() {
+ _ = os.RemoveAll(basePath)
+ }()
+ paths, err := os.MkdirTemp(basePath, "paths")
+ require.NoError(t, err)
+ dirPath, err := os.MkdirTemp(paths, "dir")
+ require.NoError(t, err)
+ require.NoError(t, os.WriteFile(path.Join(paths, "foo"), []byte("foo"), 0o700)) // nolint: gosec
+ require.NoError(t, os.WriteFile(path.Join(dirPath, "bar"), []byte("bar"), 0o700)) // nolint: gosec
+
+ testCases := []struct {
+ name string
+ paths []string
+ expectDirs []string
+ expectFiles []string
+ }{
+ {
+ name: "get file and dir path",
+ paths: []string{
+ dirPath,
+ path.Join(paths, "foo"),
+ },
+ expectDirs: []string{
+ dirPath,
+ },
+ expectFiles: []string{
+ path.Join(paths, "foo"),
+ },
+ },
+ {
+ name: "overlap file path will be ignored",
+ paths: []string{
+ dirPath, path.Join(dirPath, "bar"),
+ },
+ expectDirs: []string{
+ dirPath,
+ },
+ expectFiles: []string{},
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ dirs, files := ListDirsAndFiles(tc.paths)
+ require.ElementsMatch(t, dirs.UnsortedList(), tc.expectDirs)
+ require.ElementsMatch(t, files.UnsortedList(), tc.expectFiles)
+ })
+ }
+}
+
+func TestGetParentDirs(t *testing.T) {
+ aPaths := path.Join("a")
+ bPaths := path.Join("a", "b")
+ cPaths := path.Join("a", "b", "c")
+
+ testCases := []struct {
+ name string
+ paths []string
+ expectParentDirs []string
+ }{
+ {
+ name: "all files",
+ paths: []string{
+ path.Join(cPaths, "foo"),
+ path.Join(bPaths, "bar"),
+ },
+ expectParentDirs: []string{
+ cPaths,
+ bPaths,
+ },
+ },
+ {
+ name: "all dirs",
+ paths: []string{
+ bPaths + "/",
+ cPaths + "/",
+ },
+ expectParentDirs: []string{
+ bPaths,
+ cPaths,
+ },
+ },
+ {
+ name: "mixed files and dirs",
+ paths: []string{
+ path.Join(cPaths, "foo"),
+ path.Join(cPaths, "bar"),
+ path.Join(bPaths, "foo"),
+ path.Join(bPaths, "bar"),
+ aPaths + "/",
+ bPaths + "/",
+ cPaths + "/",
+ },
+ expectParentDirs: []string{
+ cPaths,
+ bPaths,
+ aPaths,
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ parents := GetParentDirs(tc.paths)
+ require.ElementsMatch(t, parents.UnsortedList(), tc.expectParentDirs)
+ })
+ }
+}
diff --git a/internal/utils/protocov/protocov.go b/internal/utils/protocov/protocov.go
index 6533f84c543..2c5693ee9a3 100644
--- a/internal/utils/protocov/protocov.go
+++ b/internal/utils/protocov/protocov.go
@@ -12,30 +12,30 @@ import (
"google.golang.org/protobuf/types/known/anypb"
)
-const (
- APIPrefix = "type.googleapis.com/"
-)
-
-var marshalOpts = proto.MarshalOptions{}
+// Deprecated: error should not be ignored, use ToAnyWithValidation instead.
+func ToAny(msg proto.Message) *anypb.Any {
+ res, err := ToAnyWithValidation(msg)
+ if err != nil {
+ return nil
+ }
+ return res
+}
-func ToAnyWithError(msg proto.Message) (*anypb.Any, error) {
+func ToAnyWithValidation(msg proto.Message) (*anypb.Any, error) {
if msg == nil {
return nil, errors.New("empty message received")
}
- b, err := marshalOpts.Marshal(msg)
- if err != nil {
- return nil, err
+
+ // If the message has a ValidateAll method, call it before marshaling.
+ if validator, ok := msg.(interface{ ValidateAll() error }); ok {
+ if err := validator.ValidateAll(); err != nil {
+ return nil, err
+ }
}
- return &anypb.Any{
- TypeUrl: APIPrefix + string(msg.ProtoReflect().Descriptor().FullName()),
- Value: b,
- }, nil
-}
-func ToAny(msg proto.Message) *anypb.Any {
- res, err := ToAnyWithError(msg)
+ any, err := anypb.New(msg)
if err != nil {
- return nil
+ return nil, err
}
- return res
+ return any, nil
}
diff --git a/internal/utils/ratelimit/unit.go b/internal/utils/ratelimit/unit.go
new file mode 100644
index 00000000000..94c8c7f6fbe
--- /dev/null
+++ b/internal/utils/ratelimit/unit.go
@@ -0,0 +1,36 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package ratelimit
+
+import (
+ "google.golang.org/protobuf/types/known/durationpb"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/ir"
+)
+
+func UnitToSeconds(unit egv1a1.RateLimitUnit) int64 {
+ var seconds int64
+
+ switch unit {
+ case egv1a1.RateLimitUnitSecond:
+ seconds = 1
+ case egv1a1.RateLimitUnitMinute:
+ seconds = 60
+ case egv1a1.RateLimitUnitHour:
+ seconds = 60 * 60
+ case egv1a1.RateLimitUnitDay:
+ seconds = 60 * 60 * 24
+ }
+ return seconds
+}
+
+func UnitToDuration(unit ir.RateLimitUnit) *durationpb.Duration {
+ seconds := UnitToSeconds(egv1a1.RateLimitUnit(unit))
+ return &durationpb.Duration{
+ Seconds: seconds,
+ }
+}
diff --git a/internal/wasm/cache.go b/internal/wasm/cache.go
index 6082a078855..785d8d3701a 100644
--- a/internal/wasm/cache.go
+++ b/internal/wasm/cache.go
@@ -247,7 +247,7 @@ func (c *localFileCache) getOrFetch(key cacheKey, opts GetOptions) (*cacheEntry,
sha := sha256.Sum256(b)
dChecksum = hex.EncodeToString(sha[:])
case "oci":
- if opts.PullSecret != nil && len(opts.PullSecret) > 0 {
+ if len(opts.PullSecret) > 0 {
isPrivate = true
}
if imageBinaryFetcher, dChecksum, err = c.prepareFetch(ctx, u, insecure, opts); err != nil {
@@ -303,7 +303,7 @@ func (c *localFileCache) prepareFetch(
imgFetcherOps := ImageFetcherOption{
Insecure: insecure,
}
- if opts.PullSecret != nil && len(opts.PullSecret) > 0 {
+ if len(opts.PullSecret) > 0 {
imgFetcherOps.PullSecret = opts.PullSecret
}
fetcher := NewImageFetcher(ctx, imgFetcherOps, c.logger)
diff --git a/internal/wasm/httpserver.go b/internal/wasm/httpserver.go
index 9b1d0b32c90..14e70a8c6dc 100644
--- a/internal/wasm/httpserver.go
+++ b/internal/wasm/httpserver.go
@@ -131,6 +131,12 @@ func (s *HTTPServer) Start(ctx context.Context) {
return
}
}()
+
+ go func() {
+ // waiting for shutdown
+ <-ctx.Done()
+ _ = s.server.Shutdown(context.Background())
+ }()
s.cache.Start(ctx)
go s.resetFailedAttempts(ctx)
}
diff --git a/internal/wasm/imagefetcher.go b/internal/wasm/imagefetcher.go
index 5c97ad5f4a4..1b8c40fcd25 100644
--- a/internal/wasm/imagefetcher.go
+++ b/internal/wasm/imagefetcher.go
@@ -54,7 +54,7 @@ type ImageFetcherOption struct {
}
func (o *ImageFetcherOption) useAnonymous() bool {
- return o.PullSecret == nil || len(o.PullSecret) == 0
+ return len(o.PullSecret) == 0
}
func (o *ImageFetcherOption) String() string {
diff --git a/internal/xds/bootstrap/bootstrap.go b/internal/xds/bootstrap/bootstrap.go
index e74620483f4..0b043bd163b 100644
--- a/internal/xds/bootstrap/bootstrap.go
+++ b/internal/xds/bootstrap/bootstrap.go
@@ -9,13 +9,15 @@ import (
// Register embed
_ "embed"
"fmt"
+ "net"
+ "strconv"
"strings"
"text/template"
"k8s.io/apimachinery/pkg/util/sets"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
- "github.com/envoyproxy/gateway/internal/utils/net"
+ netutils "github.com/envoyproxy/gateway/internal/utils/net"
"github.com/envoyproxy/gateway/internal/utils/regex"
)
@@ -25,8 +27,9 @@ const (
// envoyGatewayXdsServerHost is the DNS name of the Xds Server within Envoy Gateway.
// It defaults to the Envoy Gateway Kubernetes service.
envoyGatewayXdsServerHost = "envoy-gateway"
- // EnvoyAdminAddress is the listening address of the envoy admin interface.
- EnvoyAdminAddress = "127.0.0.1"
+ // EnvoyAdminAddress is the listening v4 address of the envoy admin interface.
+ EnvoyAdminAddress = "127.0.0.1"
+ EnvoyAdminAddressV6 = "::1"
// EnvoyAdminPort is the port used to expose admin interface.
EnvoyAdminPort = 19000
// envoyAdminAccessLogPath is the path used to expose admin access log.
@@ -39,9 +42,14 @@ const (
// DefaultWasmServerPort is the default listening port of the wasm HTTP server.
wasmServerPort = 18002
- envoyReadinessAddress = "0.0.0.0"
- EnvoyReadinessPort = 19001
- EnvoyReadinessPath = "/ready"
+ envoyReadinessAddressv4 = "0.0.0.0"
+ envoyReadinessAddressv6 = "::"
+
+ EnvoyReadinessPort = 19001
+ EnvoyReadinessPath = "/ready"
+
+ defaultSdsTrustedCAPath = "/sds/xds-trusted-ca.json"
+ defaultSdsCertificatePath = "/sds/xds-certificate.json"
)
//go:embed bootstrap.yaml.tpl
@@ -67,6 +75,12 @@ type bootstrapParameters struct {
AdminServer adminServerParameters
// ReadyServer defines the configuration for health check ready listener
ReadyServer readyServerParameters
+
+ // SdsCertificatePath defines the path to SDS certificate config.
+ SdsCertificatePath string
+ // SdsTrustedCAPath defines the path to SDS trusted CA config.
+ SdsTrustedCAPath string
+
// EnablePrometheus defines whether to enable metrics endpoint for prometheus.
EnablePrometheus bool
// EnablePrometheusCompression defines whether to enable HTTP compression on metrics endpoint for prometheus.
@@ -83,6 +97,9 @@ type bootstrapParameters struct {
StatsMatcher *StatsMatcherParameters
// OverloadManager defines the configuration of the Envoy overload manager.
OverloadManager overloadManagerParameters
+
+ // IPFamily of the Listener
+ IPFamily string
}
type serverParameters struct {
@@ -129,10 +146,22 @@ type overloadManagerParameters struct {
}
type RenderBootstrapConfigOptions struct {
+ IPFamily *egv1a1.IPFamily
ProxyMetrics *egv1a1.ProxyMetrics
+ SdsConfig SdsConfigPath
+ XdsServerHost *string
+ XdsServerPort *int32
+ WasmServerPort *int32
+ AdminServerPort *int32
+ ReadyServerPort *int32
MaxHeapSizeBytes uint64
}
+type SdsConfigPath struct {
+ Certificate string
+ TrustedCA string
+}
+
// render the stringified bootstrap config in yaml format.
func (b *bootstrapConfig) render() error {
buf := new(strings.Builder)
@@ -179,9 +208,9 @@ func GetRenderedBootstrapConfig(opts *RenderBootstrapConfigOptions) (string, err
host, port = *sink.OpenTelemetry.Host, uint32(sink.OpenTelemetry.Port)
}
if len(sink.OpenTelemetry.BackendRefs) > 0 {
- host, port = net.BackendHostAndPort(sink.OpenTelemetry.BackendRefs[0].BackendObjectReference, "")
+ host, port = netutils.BackendHostAndPort(sink.OpenTelemetry.BackendRefs[0].BackendObjectReference, "")
}
- addr := fmt.Sprintf("%s:%d", host, port)
+ addr := net.JoinHostPort(host, strconv.Itoa(int(port)))
if addresses.Has(addr) {
continue
}
@@ -234,21 +263,61 @@ func GetRenderedBootstrapConfig(opts *RenderBootstrapConfigOptions) (string, err
AccessLogPath: envoyAdminAccessLogPath,
},
ReadyServer: readyServerParameters{
- Address: envoyReadinessAddress,
+ Address: envoyReadinessAddressv4,
Port: EnvoyReadinessPort,
ReadinessPath: EnvoyReadinessPath,
},
+ SdsCertificatePath: defaultSdsCertificatePath,
+ SdsTrustedCAPath: defaultSdsTrustedCAPath,
EnablePrometheus: enablePrometheus,
EnablePrometheusCompression: enablePrometheusCompression,
PrometheusCompressionLibrary: PrometheusCompressionLibrary,
OtelMetricSinks: metricSinks,
},
}
- if opts != nil && opts.ProxyMetrics != nil && opts.ProxyMetrics.Matches != nil {
- cfg.parameters.StatsMatcher = &StatsMatcher
- }
+ // Bootstrap config override
if opts != nil {
+ if opts.ProxyMetrics != nil && opts.ProxyMetrics.Matches != nil {
+ cfg.parameters.StatsMatcher = &StatsMatcher
+ }
+
+ // Override Sds configs
+ if len(opts.SdsConfig.Certificate) > 0 {
+ cfg.parameters.SdsCertificatePath = opts.SdsConfig.Certificate
+ }
+ if len(opts.SdsConfig.TrustedCA) > 0 {
+ cfg.parameters.SdsTrustedCAPath = opts.SdsConfig.TrustedCA
+ }
+
+ if opts.XdsServerHost != nil {
+ cfg.parameters.XdsServer.Address = *opts.XdsServerHost
+ }
+
+ // Override the various server port
+ if opts.XdsServerPort != nil {
+ cfg.parameters.XdsServer.Port = *opts.XdsServerPort
+ }
+ if opts.AdminServerPort != nil {
+ cfg.parameters.AdminServer.Port = *opts.AdminServerPort
+ }
+ if opts.ReadyServerPort != nil {
+ cfg.parameters.ReadyServer.Port = *opts.ReadyServerPort
+ }
+ if opts.WasmServerPort != nil {
+ cfg.parameters.WasmServer.Port = *opts.WasmServerPort
+ }
+
+ if opts.IPFamily != nil {
+ cfg.parameters.IPFamily = string(*opts.IPFamily)
+ if *opts.IPFamily == egv1a1.IPv6 {
+ cfg.parameters.AdminServer.Address = EnvoyAdminAddressV6
+ cfg.parameters.ReadyServer.Address = envoyReadinessAddressv6
+ } else if *opts.IPFamily == egv1a1.DualStack {
+ cfg.parameters.ReadyServer.Address = envoyReadinessAddressv6
+ }
+ }
+
cfg.parameters.OverloadManager.MaxHeapSizeBytes = opts.MaxHeapSizeBytes
}
diff --git a/internal/xds/bootstrap/bootstrap.yaml.tpl b/internal/xds/bootstrap/bootstrap.yaml.tpl
index b7d26c7d4a9..e10ab4d83f0 100644
--- a/internal/xds/bootstrap/bootstrap.yaml.tpl
+++ b/internal/xds/bootstrap/bootstrap.yaml.tpl
@@ -65,9 +65,12 @@ static_resources:
- name: envoy-gateway-proxy-ready-{{ .ReadyServer.Address }}-{{ .ReadyServer.Port }}
address:
socket_address:
- address: {{ .ReadyServer.Address }}
+ address: '{{ .ReadyServer.Address }}'
port_value: {{ .ReadyServer.Port }}
protocol: TCP
+ {{- if eq .IPFamily "DualStack"}}
+ ipv4_compat: true
+ {{- end }}
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -191,13 +194,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: {{ .SdsCertificatePath }}
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: {{ .SdsTrustedCAPath }}
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -229,13 +232,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: {{ .SdsCertificatePath }}
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: {{ .SdsTrustedCAPath }}
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
diff --git a/internal/xds/bootstrap/bootstrap_test.go b/internal/xds/bootstrap/bootstrap_test.go
index 19e020c499e..d72220a0141 100644
--- a/internal/xds/bootstrap/bootstrap_test.go
+++ b/internal/xds/bootstrap/bootstrap_test.go
@@ -20,6 +20,11 @@ import (
)
func TestGetRenderedBootstrapConfig(t *testing.T) {
+ sds := SdsConfigPath{
+ Certificate: "/sds/xds-certificate.json",
+ TrustedCA: "/sds/xds-trusted-ca.json",
+ }
+
cases := []struct {
name string
opts *RenderBootstrapConfigOptions
@@ -32,6 +37,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) {
Disable: true,
},
},
+ SdsConfig: sds,
},
},
{
@@ -40,6 +46,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) {
ProxyMetrics: &egv1a1.ProxyMetrics{
Prometheus: &egv1a1.ProxyPrometheusProvider{},
},
+ SdsConfig: sds,
},
},
{
@@ -52,6 +59,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) {
},
},
},
+ SdsConfig: sds,
},
},
{
@@ -71,6 +79,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) {
},
},
},
+ SdsConfig: sds,
},
},
{
@@ -86,12 +95,14 @@ func TestGetRenderedBootstrapConfig(t *testing.T) {
OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{
Host: ptr.To("otel-collector.monitoring.svc"),
Port: 4317,
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "otel-collector",
- Namespace: ptr.To(gwapiv1.Namespace("monitoring")),
- Port: ptr.To(gwapiv1.PortNumber(4317)),
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "otel-collector",
+ Namespace: ptr.To(gwapiv1.Namespace("monitoring")),
+ Port: ptr.To(gwapiv1.PortNumber(4317)),
+ },
},
},
},
@@ -99,6 +110,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) {
},
},
},
+ SdsConfig: sds,
},
},
{
@@ -128,12 +140,31 @@ func TestGetRenderedBootstrapConfig(t *testing.T) {
},
},
},
+ SdsConfig: sds,
+ },
+ },
+ {
+ name: "custom-server-port",
+ opts: &RenderBootstrapConfigOptions{
+ XdsServerHost: ptr.To("foo.bar"),
+ XdsServerPort: ptr.To(int32(12345)),
+ WasmServerPort: ptr.To(int32(1111)),
+ AdminServerPort: ptr.To(int32(2222)),
+ ReadyServerPort: ptr.To(int32(3333)),
+ SdsConfig: sds,
},
},
{
name: "with-max-heap-size-bytes",
opts: &RenderBootstrapConfigOptions{
MaxHeapSizeBytes: 1073741824,
+ SdsConfig: sds,
+ },
+ },
+ {
+ name: "ipv6",
+ opts: &RenderBootstrapConfigOptions{
+ IPFamily: ptr.To(egv1a1.IPv6),
},
},
}
diff --git a/api/v1alpha1/validation/testdata/merge-user-bootstrap.yaml b/internal/xds/bootstrap/testdata/merge/merge-user-bootstrap.in.yaml
similarity index 100%
rename from api/v1alpha1/validation/testdata/merge-user-bootstrap.yaml
rename to internal/xds/bootstrap/testdata/merge/merge-user-bootstrap.in.yaml
diff --git a/internal/xds/bootstrap/testdata/merge/merge-user-bootstrap.out.yaml b/internal/xds/bootstrap/testdata/merge/merge-user-bootstrap.out.yaml
new file mode 100644
index 00000000000..7fcb292368a
--- /dev/null
+++ b/internal/xds/bootstrap/testdata/merge/merge-user-bootstrap.out.yaml
@@ -0,0 +1,178 @@
+admin:
+ accessLog:
+ - name: envoy.access_loggers.file
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ path: /dev/null
+ address:
+ socketAddress:
+ address: 127.0.0.1
+ portValue: 8080
+dynamicResources:
+ adsConfig:
+ apiType: DELTA_GRPC
+ grpcServices:
+ - envoyGrpc:
+ clusterName: xds_cluster
+ setNodeOnFirstMessageOnly: true
+ transportApiVersion: V3
+ cdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ ldsConfig:
+ ads: {}
+ resourceApiVersion: V3
+layeredRuntime:
+ layers:
+ - name: global_config
+ staticLayer:
+ envoy.restart_features.use_eds_cache_for_ads: true
+ re2.max_program_size.error_level: 4294967295
+ re2.max_program_size.warn_level: 1000
+overloadManager:
+ refreshInterval: 0.250s
+ resourceMonitors:
+ - name: envoy.resource_monitors.global_downstream_max_connections
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
+ maxActiveDownstreamConnections: "50000"
+staticResources:
+ clusters:
+ - connectTimeout: 0.250s
+ loadAssignment:
+ clusterName: prometheus_stats
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 127.0.0.1
+ portValue: 19000
+ name: prometheus_stats
+ type: STATIC
+ - connectTimeout: 10s
+ loadAssignment:
+ clusterName: xds_cluster
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: envoy-gateway
+ portValue: 18000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ name: xds_cluster
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ tlsCertificateSdsSecretConfigs:
+ - name: xds_certificate
+ sdsConfig:
+ pathConfigSource:
+ path: /sds/xds-certificate.json
+ resourceApiVersion: V3
+ tlsParams:
+ tlsMaximumProtocolVersion: TLSv1_3
+ validationContextSdsSecretConfig:
+ name: xds_trusted_ca
+ sdsConfig:
+ pathConfigSource:
+ path: /sds/xds-trusted-ca.json
+ resourceApiVersion: V3
+ type: STRICT_DNS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ connectionKeepalive:
+ interval: 30s
+ timeout: 5s
+ - connectTimeout: 10s
+ loadAssignment:
+ clusterName: wasm_cluster
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: envoy-gateway
+ portValue: 18002
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ name: wasm_cluster
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ tlsCertificateSdsSecretConfigs:
+ - name: xds_certificate
+ sdsConfig:
+ pathConfigSource:
+ path: /sds/xds-certificate.json
+ resourceApiVersion: V3
+ tlsParams:
+ tlsMaximumProtocolVersion: TLSv1_3
+ validationContextSdsSecretConfig:
+ name: xds_trusted_ca
+ sdsConfig:
+ pathConfigSource:
+ path: /sds/xds-trusted-ca.json
+ resourceApiVersion: V3
+ type: STRICT_DNS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions: {}
+ - connectTimeout: 0.250s
+ loadAssignment:
+ clusterName: prometheus_stats
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 127.0.0.1
+ portValue: 19000
+ name: prometheus_stats
+ type: STATIC
+ listeners:
+ - address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 19001
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ httpFilters:
+ - name: envoy.filters.http.health_check
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck
+ headers:
+ - name: :path
+ stringMatch:
+ exact: /ready
+ passThroughMode: false
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ routeConfig:
+ name: local_route
+ virtualHosts:
+ - domains:
+ - '*'
+ name: prometheus_stats
+ routes:
+ - match:
+ prefix: /stats/prometheus
+ route:
+ cluster: prometheus_stats
+ statPrefix: eg-ready-http
+ name: envoy-gateway-proxy-ready-0.0.0.0-19001
diff --git a/internal/xds/bootstrap/testdata/merge/patch-global-config.in.yaml b/internal/xds/bootstrap/testdata/merge/patch-global-config.in.yaml
new file mode 100644
index 00000000000..2035e5f3433
--- /dev/null
+++ b/internal/xds/bootstrap/testdata/merge/patch-global-config.in.yaml
@@ -0,0 +1,6 @@
+- op: add
+ path: /layered_runtime/layers/0/static_layer/envoy.restart_features.use_eds_cache_for_ads
+ value: false
+- op: add
+ path: /layered_runtime/layers/0/static_layer/envoy.something.completely.made.up
+ value: arbitrary string
diff --git a/internal/xds/bootstrap/testdata/merge/patch-global-config.out.yaml b/internal/xds/bootstrap/testdata/merge/patch-global-config.out.yaml
new file mode 100644
index 00000000000..63915cc277a
--- /dev/null
+++ b/internal/xds/bootstrap/testdata/merge/patch-global-config.out.yaml
@@ -0,0 +1,169 @@
+admin:
+ access_log:
+ - name: envoy.access_loggers.file
+ typed_config:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ path: /dev/null
+ address:
+ socket_address:
+ address: 127.0.0.1
+ port_value: 19000
+dynamic_resources:
+ ads_config:
+ api_type: DELTA_GRPC
+ grpc_services:
+ - envoy_grpc:
+ cluster_name: xds_cluster
+ set_node_on_first_message_only: true
+ transport_api_version: V3
+ cds_config:
+ ads: {}
+ resource_api_version: V3
+ lds_config:
+ ads: {}
+ resource_api_version: V3
+layered_runtime:
+ layers:
+ - name: global_config
+ static_layer:
+ envoy.restart_features.use_eds_cache_for_ads: false
+ envoy.something.completely.made.up: arbitrary string
+ re2.max_program_size.error_level: 4294967295
+ re2.max_program_size.warn_level: 1000
+overload_manager:
+ refresh_interval: 0.25s
+ resource_monitors:
+ - name: envoy.resource_monitors.global_downstream_max_connections
+ typed_config:
+ '@type': type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
+ max_active_downstream_connections: 50000
+static_resources:
+ clusters:
+ - connect_timeout: 0.250s
+ lb_policy: ROUND_ROBIN
+ load_assignment:
+ cluster_name: prometheus_stats
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: 127.0.0.1
+ port_value: 19000
+ name: prometheus_stats
+ type: STATIC
+ - connect_timeout: 10s
+ load_assignment:
+ cluster_name: xds_cluster
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway
+ port_value: 18000
+ load_balancing_weight: 1
+ load_balancing_weight: 1
+ name: xds_cluster
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+ type: STRICT_DNS
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicit_http_config:
+ http2_protocol_options:
+ connection_keepalive:
+ interval: 30s
+ timeout: 5s
+ - connect_timeout: 10s
+ load_assignment:
+ cluster_name: wasm_cluster
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway
+ port_value: 18002
+ load_balancing_weight: 1
+ load_balancing_weight: 1
+ name: wasm_cluster
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+ type: STRICT_DNS
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicit_http_config:
+ http2_protocol_options: {}
+ listeners:
+ - address:
+ socket_address:
+ address: 0.0.0.0
+ port_value: 19001
+ protocol: TCP
+ filter_chains:
+ - filters:
+ - name: envoy.filters.network.http_connection_manager
+ typed_config:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ http_filters:
+ - name: envoy.filters.http.health_check
+ typed_config:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck
+ headers:
+ - name: :path
+ string_match:
+ exact: /ready
+ pass_through_mode: false
+ - name: envoy.filters.http.router
+ typed_config:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ route_config:
+ name: local_route
+ virtual_hosts:
+ - domains:
+ - '*'
+ name: prometheus_stats
+ routes:
+ - match:
+ prefix: /stats/prometheus
+ route:
+ cluster: prometheus_stats
+ stat_prefix: eg-ready-http
+ name: envoy-gateway-proxy-ready-0.0.0.0-19001
diff --git a/internal/xds/bootstrap/testdata/render/custom-server-port.yaml b/internal/xds/bootstrap/testdata/render/custom-server-port.yaml
new file mode 100644
index 00000000000..cc3b56b399c
--- /dev/null
+++ b/internal/xds/bootstrap/testdata/render/custom-server-port.yaml
@@ -0,0 +1,168 @@
+admin:
+ access_log:
+ - name: envoy.access_loggers.file
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ path: /dev/null
+ address:
+ socket_address:
+ address: 127.0.0.1
+ port_value: 2222
+layered_runtime:
+ layers:
+ - name: global_config
+ static_layer:
+ envoy.restart_features.use_eds_cache_for_ads: true
+ re2.max_program_size.error_level: 4294967295
+ re2.max_program_size.warn_level: 1000
+dynamic_resources:
+ ads_config:
+ api_type: DELTA_GRPC
+ transport_api_version: V3
+ grpc_services:
+ - envoy_grpc:
+ cluster_name: xds_cluster
+ set_node_on_first_message_only: true
+ lds_config:
+ ads: {}
+ resource_api_version: V3
+ cds_config:
+ ads: {}
+ resource_api_version: V3
+static_resources:
+ listeners:
+ - name: envoy-gateway-proxy-ready-0.0.0.0-3333
+ address:
+ socket_address:
+ address: '0.0.0.0'
+ port_value: 3333
+ protocol: TCP
+ filter_chains:
+ - filters:
+ - name: envoy.filters.network.http_connection_manager
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ stat_prefix: eg-ready-http
+ route_config:
+ name: local_route
+ virtual_hosts:
+ - name: prometheus_stats
+ domains:
+ - "*"
+ routes:
+ - match:
+ prefix: /stats/prometheus
+ route:
+ cluster: prometheus_stats
+ http_filters:
+ - name: envoy.filters.http.health_check
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck
+ pass_through_mode: false
+ headers:
+ - name: ":path"
+ string_match:
+ exact: /ready
+ - name: envoy.filters.http.router
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ clusters:
+ - name: prometheus_stats
+ connect_timeout: 0.250s
+ type: STATIC
+ lb_policy: ROUND_ROBIN
+ load_assignment:
+ cluster_name: prometheus_stats
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: 127.0.0.1
+ port_value: 2222
+ - connect_timeout: 10s
+ load_assignment:
+ cluster_name: xds_cluster
+ endpoints:
+ - load_balancing_weight: 1
+ lb_endpoints:
+ - load_balancing_weight: 1
+ endpoint:
+ address:
+ socket_address:
+ address: foo.bar
+ port_value: 12345
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ explicit_http_config:
+ http2_protocol_options:
+ connection_keepalive:
+ interval: 30s
+ timeout: 5s
+ name: xds_cluster
+ type: STRICT_DNS
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+ - name: wasm_cluster
+ type: STRICT_DNS
+ connect_timeout: 10s
+ load_assignment:
+ cluster_name: wasm_cluster
+ endpoints:
+ - load_balancing_weight: 1
+ lb_endpoints:
+ - load_balancing_weight: 1
+ endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway
+ port_value: 1111
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ explicit_http_config:
+ http2_protocol_options: {}
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+overload_manager:
+ refresh_interval: 0.25s
+ resource_monitors:
+ - name: "envoy.resource_monitors.global_downstream_max_connections"
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
+ max_active_downstream_connections: 50000
diff --git a/internal/xds/bootstrap/testdata/render/custom-stats-matcher.yaml b/internal/xds/bootstrap/testdata/render/custom-stats-matcher.yaml
index e23e57ff515..27258e741ea 100644
--- a/internal/xds/bootstrap/testdata/render/custom-stats-matcher.yaml
+++ b/internal/xds/bootstrap/testdata/render/custom-stats-matcher.yaml
@@ -45,7 +45,7 @@ static_resources:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -124,13 +124,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -162,13 +162,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
diff --git a/internal/xds/bootstrap/testdata/render/disable-prometheus.yaml b/internal/xds/bootstrap/testdata/render/disable-prometheus.yaml
index 02902fec330..1e3ba1994dd 100644
--- a/internal/xds/bootstrap/testdata/render/disable-prometheus.yaml
+++ b/internal/xds/bootstrap/testdata/render/disable-prometheus.yaml
@@ -34,7 +34,7 @@ static_resources:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -91,13 +91,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -129,13 +129,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
diff --git a/internal/xds/bootstrap/testdata/render/enable-prometheus-gzip-compression.yaml b/internal/xds/bootstrap/testdata/render/enable-prometheus-gzip-compression.yaml
index 39219431305..20eedcb3be8 100644
--- a/internal/xds/bootstrap/testdata/render/enable-prometheus-gzip-compression.yaml
+++ b/internal/xds/bootstrap/testdata/render/enable-prometheus-gzip-compression.yaml
@@ -34,7 +34,7 @@ static_resources:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -120,13 +120,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -158,13 +158,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
diff --git a/internal/xds/bootstrap/testdata/render/enable-prometheus.yaml b/internal/xds/bootstrap/testdata/render/enable-prometheus.yaml
index f2e0b49b859..162569bcaf9 100644
--- a/internal/xds/bootstrap/testdata/render/enable-prometheus.yaml
+++ b/internal/xds/bootstrap/testdata/render/enable-prometheus.yaml
@@ -34,7 +34,7 @@ static_resources:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -113,13 +113,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -151,13 +151,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
diff --git a/internal/xds/bootstrap/testdata/render/ipv6.yaml b/internal/xds/bootstrap/testdata/render/ipv6.yaml
new file mode 100644
index 00000000000..63395e20f7a
--- /dev/null
+++ b/internal/xds/bootstrap/testdata/render/ipv6.yaml
@@ -0,0 +1,168 @@
+admin:
+ access_log:
+ - name: envoy.access_loggers.file
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ path: /dev/null
+ address:
+ socket_address:
+ address: ::1
+ port_value: 19000
+layered_runtime:
+ layers:
+ - name: global_config
+ static_layer:
+ envoy.restart_features.use_eds_cache_for_ads: true
+ re2.max_program_size.error_level: 4294967295
+ re2.max_program_size.warn_level: 1000
+dynamic_resources:
+ ads_config:
+ api_type: DELTA_GRPC
+ transport_api_version: V3
+ grpc_services:
+ - envoy_grpc:
+ cluster_name: xds_cluster
+ set_node_on_first_message_only: true
+ lds_config:
+ ads: {}
+ resource_api_version: V3
+ cds_config:
+ ads: {}
+ resource_api_version: V3
+static_resources:
+ listeners:
+ - name: envoy-gateway-proxy-ready-::-19001
+ address:
+ socket_address:
+ address: '::'
+ port_value: 19001
+ protocol: TCP
+ filter_chains:
+ - filters:
+ - name: envoy.filters.network.http_connection_manager
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ stat_prefix: eg-ready-http
+ route_config:
+ name: local_route
+ virtual_hosts:
+ - name: prometheus_stats
+ domains:
+ - "*"
+ routes:
+ - match:
+ prefix: /stats/prometheus
+ route:
+ cluster: prometheus_stats
+ http_filters:
+ - name: envoy.filters.http.health_check
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck
+ pass_through_mode: false
+ headers:
+ - name: ":path"
+ string_match:
+ exact: /ready
+ - name: envoy.filters.http.router
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ clusters:
+ - name: prometheus_stats
+ connect_timeout: 0.250s
+ type: STATIC
+ lb_policy: ROUND_ROBIN
+ load_assignment:
+ cluster_name: prometheus_stats
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: ::1
+ port_value: 19000
+ - connect_timeout: 10s
+ load_assignment:
+ cluster_name: xds_cluster
+ endpoints:
+ - load_balancing_weight: 1
+ lb_endpoints:
+ - load_balancing_weight: 1
+ endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway
+ port_value: 18000
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ explicit_http_config:
+ http2_protocol_options:
+ connection_keepalive:
+ interval: 30s
+ timeout: 5s
+ name: xds_cluster
+ type: STRICT_DNS
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+ - name: wasm_cluster
+ type: STRICT_DNS
+ connect_timeout: 10s
+ load_assignment:
+ cluster_name: wasm_cluster
+ endpoints:
+ - load_balancing_weight: 1
+ lb_endpoints:
+ - load_balancing_weight: 1
+ endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway
+ port_value: 18002
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ explicit_http_config:
+ http2_protocol_options: {}
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+overload_manager:
+ refresh_interval: 0.25s
+ resource_monitors:
+ - name: "envoy.resource_monitors.global_downstream_max_connections"
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
+ max_active_downstream_connections: 50000
diff --git a/internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml b/internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml
index 6079f777dc8..27521b3c3fa 100644
--- a/internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml
+++ b/internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml
@@ -41,7 +41,7 @@ static_resources:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -116,13 +116,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -154,13 +154,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
diff --git a/internal/xds/bootstrap/testdata/render/otel-metrics.yaml b/internal/xds/bootstrap/testdata/render/otel-metrics.yaml
index 6079f777dc8..27521b3c3fa 100644
--- a/internal/xds/bootstrap/testdata/render/otel-metrics.yaml
+++ b/internal/xds/bootstrap/testdata/render/otel-metrics.yaml
@@ -41,7 +41,7 @@ static_resources:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -116,13 +116,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -154,13 +154,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
diff --git a/internal/xds/bootstrap/testdata/render/with-max-heap-size-bytes.yaml b/internal/xds/bootstrap/testdata/render/with-max-heap-size-bytes.yaml
index 9eebf9d010c..a50a221b48f 100644
--- a/internal/xds/bootstrap/testdata/render/with-max-heap-size-bytes.yaml
+++ b/internal/xds/bootstrap/testdata/render/with-max-heap-size-bytes.yaml
@@ -34,7 +34,7 @@ static_resources:
- name: envoy-gateway-proxy-ready-0.0.0.0-19001
address:
socket_address:
- address: 0.0.0.0
+ address: '0.0.0.0'
port_value: 19001
protocol: TCP
filter_chains:
@@ -113,13 +113,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
- name: wasm_cluster
type: STRICT_DNS
@@ -151,13 +151,13 @@ static_resources:
- name: xds_certificate
sds_config:
path_config_source:
- path: "/sds/xds-certificate.json"
+ path: /sds/xds-certificate.json
resource_api_version: V3
validation_context_sds_secret_config:
name: xds_trusted_ca
sds_config:
path_config_source:
- path: "/sds/xds-trusted-ca.json"
+ path: /sds/xds-trusted-ca.json
resource_api_version: V3
overload_manager:
refresh_interval: 0.25s
diff --git a/api/v1alpha1/validation/testdata/different-dynamic-resources-user-bootstrap.yaml b/internal/xds/bootstrap/testdata/validate/different-dynamic-resources-user-bootstrap.yaml
similarity index 100%
rename from api/v1alpha1/validation/testdata/different-dynamic-resources-user-bootstrap.yaml
rename to internal/xds/bootstrap/testdata/validate/different-dynamic-resources-user-bootstrap.yaml
diff --git a/api/v1alpha1/validation/testdata/different-xds-cluster-address-bootstrap.yaml b/internal/xds/bootstrap/testdata/validate/different-xds-cluster-address-bootstrap.yaml
similarity index 100%
rename from api/v1alpha1/validation/testdata/different-xds-cluster-address-bootstrap.yaml
rename to internal/xds/bootstrap/testdata/validate/different-xds-cluster-address-bootstrap.yaml
diff --git a/api/v1alpha1/validation/testdata/missing-admin-address-user-bootstrap.yaml b/internal/xds/bootstrap/testdata/validate/missing-admin-address-user-bootstrap.yaml
similarity index 100%
rename from api/v1alpha1/validation/testdata/missing-admin-address-user-bootstrap.yaml
rename to internal/xds/bootstrap/testdata/validate/missing-admin-address-user-bootstrap.yaml
diff --git a/api/v1alpha1/validation/testdata/valid-user-bootstrap.yaml b/internal/xds/bootstrap/testdata/validate/valid-user-bootstrap.yaml
similarity index 100%
rename from api/v1alpha1/validation/testdata/valid-user-bootstrap.yaml
rename to internal/xds/bootstrap/testdata/validate/valid-user-bootstrap.yaml
diff --git a/internal/xds/bootstrap/util.go b/internal/xds/bootstrap/util.go
index e00294e2715..701da1f102a 100644
--- a/internal/xds/bootstrap/util.go
+++ b/internal/xds/bootstrap/util.go
@@ -9,33 +9,57 @@ import (
"fmt"
bootstrapv3 "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3"
+ "k8s.io/utils/ptr"
+ "sigs.k8s.io/yaml"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils/jsonpatch"
"github.com/envoyproxy/gateway/internal/utils/proto"
_ "github.com/envoyproxy/gateway/internal/xds/extensions" // DON'T REMOVE: import of all extensions
)
// ApplyBootstrapConfig applies the bootstrap config to the default bootstrap config and return the result config.
+// The defaultBootstrap is expected to be a YAML string
func ApplyBootstrapConfig(boostrapConfig *egv1a1.ProxyBootstrap, defaultBootstrap string) (string, error) {
bootstrapType := boostrapConfig.Type
- if bootstrapType != nil && *bootstrapType == egv1a1.BootstrapTypeMerge {
+ if bootstrapType == nil {
+ // The documentation defines that a nil bootstrapType defaults to the "Replace" operation
+ bootstrapType = ptr.To(egv1a1.BootstrapTypeReplace)
+ }
+ switch *bootstrapType {
+ case egv1a1.BootstrapTypeMerge:
mergedBootstrap, err := mergeBootstrap(defaultBootstrap, boostrapConfig.Value)
if err != nil {
return "", err
}
return mergedBootstrap, nil
+ case egv1a1.BootstrapTypeReplace:
+ // CEL validates that Value will not be nil
+ return *boostrapConfig.Value, nil
+ case egv1a1.BootstrapTypeJSONPatch:
+ patchedBootstrap, err := jsonPatchBootstrap(defaultBootstrap, boostrapConfig.JSONPatches)
+ if err != nil {
+ return "", err
+ }
+ return patchedBootstrap, nil
+ default:
+ // This is unreachable code due to the CEL validation on egv1a1.ProxyBootstrap
+ return defaultBootstrap, fmt.Errorf("unsupported bootstrap patch type %s", *bootstrapType)
}
- return boostrapConfig.Value, nil
}
-func mergeBootstrap(base, override string) (string, error) {
+func mergeBootstrap(base string, override *string) (string, error) {
+ if override == nil {
+ return base, nil
+ }
dst := &bootstrapv3.Bootstrap{}
if err := proto.FromYAML([]byte(base), dst); err != nil {
return "", fmt.Errorf("failed to parse default bootstrap config: %w", err)
}
src := &bootstrapv3.Bootstrap{}
- if err := proto.FromYAML([]byte(override), src); err != nil {
+ if err := proto.FromYAML([]byte(*override), src); err != nil {
return "", fmt.Errorf("failed to parse override bootstrap config: %w", err)
}
@@ -52,3 +76,26 @@ func mergeBootstrap(base, override string) (string, error) {
return string(data), nil
}
+
+func jsonPatchBootstrap(baseYAML string, patches []egv1a1.JSONPatchOperation) (string, error) {
+ jsonBytes, err := yaml.YAMLToJSON([]byte(baseYAML))
+ if err != nil {
+ return baseYAML, err
+ }
+ translatedPatches := []ir.JSONPatchOperation{}
+ for _, p := range patches {
+ translatedPatches = append(translatedPatches, ir.JSONPatchOperation{
+ Op: ir.TranslateJSONPatchOp(p.Op),
+ Path: p.Path,
+ JSONPath: p.JSONPath,
+ From: p.From,
+ Value: p.Value,
+ })
+ }
+ jsonBytes, err = jsonpatch.ApplyJSONPatches(jsonBytes, translatedPatches...)
+ if err != nil {
+ return baseYAML, err
+ }
+ yamlBytes, err := yaml.JSONToYAML(jsonBytes)
+ return string(yamlBytes), err
+}
diff --git a/internal/xds/bootstrap/util_test.go b/internal/xds/bootstrap/util_test.go
index 5591d0e4f53..bfa5d191c46 100644
--- a/internal/xds/bootstrap/util_test.go
+++ b/internal/xds/bootstrap/util_test.go
@@ -14,6 +14,7 @@ import (
"github.com/stretchr/testify/require"
"k8s.io/utils/ptr"
+ "sigs.k8s.io/yaml"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
)
@@ -34,6 +35,13 @@ func TestApplyBootstrapConfig(t *testing.T) {
},
defaultBootstrap: str,
},
+ {
+ name: "merge-user-bootstrap",
+ boostrapConfig: &egv1a1.ProxyBootstrap{
+ Type: ptr.To(egv1a1.BootstrapTypeMerge),
+ },
+ defaultBootstrap: str,
+ },
{
name: "stats_sinks",
boostrapConfig: &egv1a1.ProxyBootstrap{
@@ -41,6 +49,13 @@ func TestApplyBootstrapConfig(t *testing.T) {
},
defaultBootstrap: str,
},
+ {
+ name: "patch-global-config",
+ boostrapConfig: &egv1a1.ProxyBootstrap{
+ Type: ptr.To(egv1a1.BootstrapTypeJSONPatch),
+ },
+ defaultBootstrap: str,
+ },
}
for _, tc := range cases {
@@ -48,7 +63,14 @@ func TestApplyBootstrapConfig(t *testing.T) {
in, err := loadData(tc.name, "in")
require.NoError(t, err)
- tc.boostrapConfig.Value = in
+ switch *tc.boostrapConfig.Type {
+ case egv1a1.BootstrapTypeJSONPatch:
+ err = yaml.Unmarshal([]byte(in), &tc.boostrapConfig.JSONPatches)
+ require.NoError(t, err)
+ default:
+ tc.boostrapConfig.Value = &in
+ }
+
data, err := ApplyBootstrapConfig(tc.boostrapConfig, tc.defaultBootstrap)
require.NoError(t, err)
diff --git a/internal/xds/bootstrap/validate.go b/internal/xds/bootstrap/validate.go
new file mode 100644
index 00000000000..5e08db72957
--- /dev/null
+++ b/internal/xds/bootstrap/validate.go
@@ -0,0 +1,89 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package bootstrap
+
+import (
+ "fmt"
+
+ bootstrapv3 "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3"
+ clusterv3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
+ "github.com/google/go-cmp/cmp"
+ "google.golang.org/protobuf/testing/protocmp"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/utils/proto"
+ _ "github.com/envoyproxy/gateway/internal/xds/extensions" // DON'T REMOVE: import of all extensions
+)
+
+func fetchAndPatchBootstrap(boostrapConfig *egv1a1.ProxyBootstrap) (*bootstrapv3.Bootstrap, *bootstrapv3.Bootstrap, error) {
+ defaultBootstrapStr, err := GetRenderedBootstrapConfig(nil)
+ if err != nil {
+ return nil, nil, err
+ }
+ defaultBootstrap := &bootstrapv3.Bootstrap{}
+ if err := proto.FromYAML([]byte(defaultBootstrapStr), defaultBootstrap); err != nil {
+ return nil, nil, fmt.Errorf("unable to unmarshal default bootstrap: %w", err)
+ }
+ if err := defaultBootstrap.Validate(); err != nil {
+ return nil, nil, fmt.Errorf("default bootstrap validation failed: %w", err)
+ }
+ // Validate user bootstrap config
+ patchedYaml, err := ApplyBootstrapConfig(boostrapConfig, defaultBootstrapStr)
+ if err != nil {
+ return nil, nil, err
+ }
+ patchedBootstrap := &bootstrapv3.Bootstrap{}
+ if err := proto.FromYAML([]byte(patchedYaml), patchedBootstrap); err != nil {
+ return nil, nil, fmt.Errorf("unable to unmarshal user bootstrap: %w", err)
+ }
+ if err := patchedBootstrap.Validate(); err != nil {
+ return nil, nil, fmt.Errorf("validation failed for user bootstrap: %w", err)
+ }
+ return patchedBootstrap, defaultBootstrap, err
+}
+
+// Validate ensures that after applying the provided bootstrap configuration, the resulting
+// bootstrap is still OK.
+// This code previously was part of the validate logic in api/v1alpha1/validate, but was moved
+// here to prevent code in the api packages from accessing code from the internal packages.
+func Validate(boostrapConfig *egv1a1.ProxyBootstrap) error {
+ if boostrapConfig == nil {
+ return nil
+ }
+ // Validate user bootstrap config
+ // TODO: need validate when enable prometheus?
+ userBootstrap, defaultBootstrap, err := fetchAndPatchBootstrap(boostrapConfig)
+ if err != nil {
+ return err
+ }
+
+ // Ensure dynamic resources config is same
+ if userBootstrap.DynamicResources == nil ||
+ cmp.Diff(userBootstrap.DynamicResources, defaultBootstrap.DynamicResources, protocmp.Transform()) != "" {
+ return fmt.Errorf("dynamic_resources cannot be modified")
+ }
+
+ // Ensure that the xds_cluster config is same
+ var userXdsCluster, defaultXdsCluster *clusterv3.Cluster
+ for _, cluster := range userBootstrap.StaticResources.Clusters {
+ if cluster.Name == "xds_cluster" {
+ userXdsCluster = cluster
+ break
+ }
+ }
+ for _, cluster := range defaultBootstrap.StaticResources.Clusters {
+ if cluster.Name == "xds_cluster" {
+ defaultXdsCluster = cluster
+ break
+ }
+ }
+ if userXdsCluster == nil ||
+ cmp.Diff(userXdsCluster.LoadAssignment, defaultXdsCluster.LoadAssignment, protocmp.Transform()) != "" {
+ return fmt.Errorf("xds_cluster's loadAssigntment cannot be modified")
+ }
+
+ return nil
+}
diff --git a/internal/xds/bootstrap/validate_test.go b/internal/xds/bootstrap/validate_test.go
new file mode 100644
index 00000000000..9c6791fea3b
--- /dev/null
+++ b/internal/xds/bootstrap/validate_test.go
@@ -0,0 +1,76 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package bootstrap
+
+import (
+ // Register embed
+ _ "embed"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+)
+
+var (
+ //go:embed testdata/validate/valid-user-bootstrap.yaml
+ validUserBootstrap string
+ //go:embed testdata/validate/missing-admin-address-user-bootstrap.yaml
+ missingAdminAddressUserBootstrap string
+ //go:embed testdata/validate/different-dynamic-resources-user-bootstrap.yaml
+ differentDynamicResourcesUserBootstrap string
+ //go:embed testdata/validate/different-xds-cluster-address-bootstrap.yaml
+ differentXdsClusterAddressBootstrap string
+)
+
+func TestValidateBootstrap(t *testing.T) {
+ testCases := []struct {
+ name string
+ bootstrap *egv1a1.ProxyBootstrap
+ expected bool
+ }{
+ {
+ name: "valid user bootstrap replace type",
+ bootstrap: &egv1a1.ProxyBootstrap{
+ Value: &validUserBootstrap,
+ },
+ expected: true,
+ },
+ {
+ name: "user bootstrap with missing admin address",
+ bootstrap: &egv1a1.ProxyBootstrap{
+ Value: &missingAdminAddressUserBootstrap,
+ },
+ expected: false,
+ },
+ {
+ name: "user bootstrap with different dynamic resources",
+ bootstrap: &egv1a1.ProxyBootstrap{
+ Value: &differentDynamicResourcesUserBootstrap,
+ },
+ expected: false,
+ },
+ {
+ name: "user bootstrap with different xds_cluster endpoint",
+ bootstrap: &egv1a1.ProxyBootstrap{
+ Value: &differentXdsClusterAddressBootstrap,
+ },
+ expected: false,
+ },
+ }
+
+ for i := range testCases {
+ tc := testCases[i]
+ t.Run(tc.name, func(t *testing.T) {
+ err := Validate(tc.bootstrap)
+ if tc.expected {
+ require.NoError(t, err)
+ } else {
+ require.Error(t, err)
+ }
+ })
+ }
+}
diff --git a/internal/xds/extensions/extensions.gen.go b/internal/xds/extensions/extensions.gen.go
index 811bc2ab444..08ac37d8e58 100644
--- a/internal/xds/extensions/extensions.gen.go
+++ b/internal/xds/extensions/extensions.gen.go
@@ -18,13 +18,7 @@ import (
_ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/http/squash/v3"
_ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/http/sxg/v3alpha"
_ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/client_ssl_auth/v3"
- _ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/action/v3"
- _ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3"
- _ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3"
_ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/codecs/kafka/v3"
- _ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3"
- _ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/router/v3"
- _ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/v3"
_ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/golang/v3alpha"
_ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/kafka_broker/v3"
_ "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/kafka_mesh/v3alpha"
@@ -137,7 +131,7 @@ import (
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/oauth2/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/on_demand/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/original_src/v3"
- _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/proto_message_logging/v3"
+ _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/proto_message_extraction/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rate_limit_quota/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ratelimit/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rbac/v3"
@@ -161,6 +155,12 @@ import (
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/dubbo_proxy/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/echo/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/ext_authz/v3"
+ _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/action/v3"
+ _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3"
+ _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3"
+ _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/matcher/v3"
+ _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/router/v3"
+ _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/local_ratelimit/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/mongo_proxy/v3"
@@ -223,6 +223,7 @@ import (
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/common_inputs/ssl/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/input_matchers/consistent_hashing/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/input_matchers/ip/v3"
+ _ "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/input_matchers/metadata/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/input_matchers/runtime_fraction/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/network/dns_resolver/apple/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/network/dns_resolver/cares/v3"
@@ -242,6 +243,7 @@ import (
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/rbac/matchers/upstream_ip_port/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/regex_engines/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/request_id/uuid/v3"
+ _ "github.com/envoyproxy/go-control-plane/envoy/extensions/resource_monitors/cpu_utilization/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/resource_monitors/downstream_connections/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/resource_monitors/fixed_heap/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/extensions/resource_monitors/injected_resource/v3"
@@ -291,6 +293,7 @@ import (
_ "github.com/envoyproxy/go-control-plane/envoy/service/metrics/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/service/rate_limit_quota/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/service/ratelimit/v3"
+ _ "github.com/envoyproxy/go-control-plane/envoy/service/redis_auth/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/service/route/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/service/runtime/v3"
_ "github.com/envoyproxy/go-control-plane/envoy/service/secret/v3"
diff --git a/internal/xds/server/runner/runner.go b/internal/xds/server/runner/runner.go
index d8acab8d951..bd2e0c64eb4 100644
--- a/internal/xds/server/runner/runner.go
+++ b/internal/xds/server/runner/runner.go
@@ -7,12 +7,9 @@ package runner
import (
"context"
- "crypto/rand"
"crypto/tls"
- "crypto/x509"
"fmt"
"net"
- "os"
"strconv"
"time"
@@ -29,6 +26,7 @@ import (
"google.golang.org/grpc/keepalive"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/crypto"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/message"
"github.com/envoyproxy/gateway/internal/xds/bootstrap"
@@ -39,15 +37,23 @@ import (
const (
// XdsServerAddress is the listening address of the xds-server.
XdsServerAddress = "0.0.0.0"
- // xdsTLSCertFilename is the fully qualified path of the file containing the
+
+ // Default certificates path for envoy-gateway with Kubernetes provider.
+ // xdsTLSCertFilepath is the fully qualified path of the file containing the
// xDS server TLS certificate.
- xdsTLSCertFilename = "/certs/tls.crt"
- // xdsTLSKeyFilename is the fully qualified path of the file containing the
+ xdsTLSCertFilepath = "/certs/tls.crt"
+ // xdsTLSKeyFilepath is the fully qualified path of the file containing the
// xDS server TLS key.
- xdsTLSKeyFilename = "/certs/tls.key"
- // xdsTLSCaFilename is the fully qualified path of the file containing the
+ xdsTLSKeyFilepath = "/certs/tls.key"
+ // xdsTLSCaFilepath is the fully qualified path of the file containing the
// xDS server trusted CA certificate.
- xdsTLSCaFilename = "/certs/ca.crt"
+ xdsTLSCaFilepath = "/certs/ca.crt"
+
+ // TODO: Make these path configurable.
+ // Default certificates path for envoy-gateway with Host infrastructure provider.
+ localTLSCertFilepath = "/tmp/envoy-gateway/certs/envoy-gateway/tls.crt"
+ localTLSKeyFilepath = "/tmp/envoy-gateway/certs/envoy-gateway/tls.key"
+ localTLSCaFilepath = "/tmp/envoy-gateway/certs/envoy-gateway/ca.crt"
)
type Config struct {
@@ -76,8 +82,13 @@ func (r *Runner) Start(ctx context.Context) (err error) {
// Set up the gRPC server and register the xDS handler.
// Create SnapshotCache before start subscribeAndTranslate,
// prevent panics in case cache is nil.
- cfg := r.tlsConfig(xdsTLSCertFilename, xdsTLSKeyFilename, xdsTLSCaFilename)
- r.grpc = grpc.NewServer(grpc.Creds(credentials.NewTLS(cfg)), grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{
+ tlsConfig, err := r.loadTLSConfig()
+ if err != nil {
+ return fmt.Errorf("failed to load TLS config: %w", err)
+ }
+ r.Logger.Info("loaded TLS certificate and key")
+
+ r.grpc = grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsConfig)), grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{
MinTime: 15 * time.Second,
PermitWithoutStream: true,
}))
@@ -160,44 +171,22 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
r.Logger.Info("subscriber shutting down")
}
-func (r *Runner) tlsConfig(cert, key, ca string) *tls.Config {
- loadConfig := func() (*tls.Config, error) {
- cert, err := tls.LoadX509KeyPair(cert, key)
+func (r *Runner) loadTLSConfig() (tlsConfig *tls.Config, err error) {
+ switch {
+ case r.EnvoyGateway.Provider.IsRunningOnKubernetes():
+ tlsConfig, err = crypto.LoadTLSConfig(xdsTLSCertFilepath, xdsTLSKeyFilepath, xdsTLSCaFilepath)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("failed to create tls config: %w", err)
}
- // Load the CA cert.
- ca, err := os.ReadFile(ca)
+ case r.EnvoyGateway.Provider.IsRunningOnHost():
+ tlsConfig, err = crypto.LoadTLSConfig(localTLSCertFilepath, localTLSKeyFilepath, localTLSCaFilepath)
if err != nil {
- return nil, err
- }
-
- certPool := x509.NewCertPool()
- if !certPool.AppendCertsFromPEM(ca) {
- return nil, fmt.Errorf("failed to parse CA certificate")
+ return nil, fmt.Errorf("failed to create tls config: %w", err)
}
- return &tls.Config{
- Certificates: []tls.Certificate{cert},
- ClientAuth: tls.RequireAndVerifyClientCert,
- ClientCAs: certPool,
- MinVersion: tls.VersionTLS13,
- }, nil
- }
-
- // Attempt to load certificates and key to catch configuration errors early.
- if _, lerr := loadConfig(); lerr != nil {
- r.Logger.Error(lerr, "failed to load certificate and key")
- }
- r.Logger.Info("loaded TLS certificate and key")
-
- return &tls.Config{
- MinVersion: tls.VersionTLS13,
- ClientAuth: tls.RequireAndVerifyClientCert,
- Rand: rand.Reader,
- GetConfigForClient: func(*tls.ClientHelloInfo) (*tls.Config, error) {
- return loadConfig()
- },
+ default:
+ return nil, fmt.Errorf("no valid tls certificates")
}
+ return
}
diff --git a/internal/xds/server/runner/runner_test.go b/internal/xds/server/runner/runner_test.go
index 45f59da0edc..e0517d1fa0d 100644
--- a/internal/xds/server/runner/runner_test.go
+++ b/internal/xds/server/runner/runner_test.go
@@ -10,6 +10,7 @@ import (
"crypto/tls"
"crypto/x509"
"errors"
+ "io"
"net"
"os"
"path/filepath"
@@ -23,9 +24,8 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
- egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/crypto"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
- "github.com/envoyproxy/gateway/internal/logging"
"github.com/envoyproxy/gateway/internal/xds/bootstrap"
)
@@ -107,15 +107,10 @@ func TestTLSConfig(t *testing.T) {
require.NoError(t, err)
// Start a dummy server.
- logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+ tlsCfg, err := crypto.LoadTLSConfig(certFile, keyFile, caFile)
+ require.NoError(t, err)
- cfg := &Config{
- Server: config.Server{
- Logger: logger,
- },
- }
- r := New(cfg)
- g := grpc.NewServer(grpc.Creds(credentials.NewTLS(r.tlsConfig(certFile, keyFile, caFile))))
+ g := grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsCfg)))
if g == nil {
t.Error("failed to create server")
}
@@ -131,7 +126,6 @@ func TestTLSConfig(t *testing.T) {
defer g.GracefulStop()
for name, tc := range tests {
- tc := tc
t.Run(name, func(t *testing.T) {
// Store certificate and key to temp dir used by serveContext.
err = tc.serverCredentials.WritePEM(certFile, keyFile)
@@ -157,6 +151,7 @@ func tryConnect(address string, clientCert tls.Certificate, caCertPool *x509.Cer
ServerName: "localhost",
MinVersion: tls.VersionTLS13,
Certificates: []tls.Certificate{clientCert},
+ NextProtos: []string{"h2"},
RootCAs: caCertPool,
}
conn, err := tls.Dial("tcp", address, clientConfig)
@@ -181,6 +176,10 @@ func peekError(conn net.Conn) error {
_ = conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
_, err := conn.Read(make([]byte, 1))
if err != nil {
+ if errors.Is(err, io.EOF) {
+ return nil
+ }
+
var netErr net.Error
if !errors.As(netErr, &netErr) || !netErr.Timeout() {
return err
diff --git a/internal/xds/translator/accesslog.go b/internal/xds/translator/accesslog.go
index 01c448b65e9..265e3ed8a9c 100644
--- a/internal/xds/translator/accesslog.go
+++ b/internal/xds/translator/accesslog.go
@@ -6,7 +6,6 @@
package translator
import (
- "errors"
"sort"
"strings"
@@ -22,7 +21,6 @@ import (
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
otlpcommonv1 "go.opentelemetry.io/proto/otlp/common/v1"
"golang.org/x/exp/maps"
- "google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/structpb"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
@@ -90,15 +88,24 @@ var (
}
)
-func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLog {
+func buildXdsAccessLog(al *ir.AccessLog, accessLogType ir.ProxyAccessLogType) ([]*accesslog.AccessLog, error) {
if al == nil {
- return nil
+ return nil, nil
}
totalLen := len(al.Text) + len(al.JSON) + len(al.OpenTelemetry)
accessLogs := make([]*accesslog.AccessLog, 0, totalLen)
+
// handle text file access logs
for _, text := range al.Text {
+ // Filter out logs that are not Global or match the desired access log type
+ if !(text.LogType == nil || *text.LogType == accessLogType) {
+ continue
+ }
+
+ // NR is only added to listener logs originating from a global log configuration
+ defaultLogTypeForListener := accessLogType == ir.ProxyAccessLogTypeListener && text.LogType == nil
+
filelog := &fileaccesslog.FileAccessLog{
Path: text.Path,
}
@@ -124,18 +131,28 @@ func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLo
filelog.GetLogFormat().Formatters = formatters
}
- // TODO: find a better way to handle this
- accesslogAny, _ := anypb.New(filelog)
+ accesslogAny, err := protocov.ToAnyWithValidation(filelog)
+ if err != nil {
+ return nil, err
+ }
accessLogs = append(accessLogs, &accesslog.AccessLog{
Name: wellknown.FileAccessLog,
ConfigType: &accesslog.AccessLog_TypedConfig{
TypedConfig: accesslogAny,
},
- Filter: buildAccessLogFilter(text.CELMatches, forListener),
+ Filter: buildAccessLogFilter(text.CELMatches, defaultLogTypeForListener),
})
}
// handle json file access logs
for _, json := range al.JSON {
+ // Filter out logs that are not Global or match the desired access log type
+ if !(json.LogType == nil || *json.LogType == accessLogType) {
+ continue
+ }
+
+ // NR is only added to listener logs originating from a global log configuration
+ defaultLogTypeForListener := accessLogType == ir.ProxyAccessLogTypeListener && json.LogType == nil
+
jsonFormat := &structpb.Struct{
Fields: make(map[string]*structpb.Value, len(json.JSON)),
}
@@ -168,17 +185,28 @@ func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLo
filelog.GetLogFormat().Formatters = formatters
}
- accesslogAny, _ := anypb.New(filelog)
+ accesslogAny, err := protocov.ToAnyWithValidation(filelog)
+ if err != nil {
+ return nil, err
+ }
accessLogs = append(accessLogs, &accesslog.AccessLog{
Name: wellknown.FileAccessLog,
ConfigType: &accesslog.AccessLog_TypedConfig{
TypedConfig: accesslogAny,
},
- Filter: buildAccessLogFilter(json.CELMatches, forListener),
+ Filter: buildAccessLogFilter(json.CELMatches, defaultLogTypeForListener),
})
}
// handle ALS access logs
for _, als := range al.ALS {
+ // Filter out logs that are not Global or match the desired access log type
+ if !(als.LogType == nil || *als.LogType == accessLogType) {
+ continue
+ }
+
+ // NR is only added to listener logs originating from a global log configuration
+ defaultLogTypeForListener := accessLogType == ir.ProxyAccessLogTypeListener && als.LogType == nil
+
cc := &grpcaccesslog.CommonGrpcAccessLogConfig{
LogName: als.LogName,
GrpcService: &cfgcore.GrpcService{
@@ -203,31 +231,45 @@ func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLo
alCfg.AdditionalResponseTrailersToLog = als.HTTP.ResponseTrailers
}
- accesslogAny, _ := anypb.New(alCfg)
+ accesslogAny, err := protocov.ToAnyWithValidation(alCfg)
+ if err != nil {
+ return nil, err
+ }
accessLogs = append(accessLogs, &accesslog.AccessLog{
Name: wellknown.HTTPGRPCAccessLog,
ConfigType: &accesslog.AccessLog_TypedConfig{
TypedConfig: accesslogAny,
},
- Filter: buildAccessLogFilter(als.CELMatches, forListener),
+ Filter: buildAccessLogFilter(als.CELMatches, defaultLogTypeForListener),
})
case egv1a1.ALSEnvoyProxyAccessLogTypeTCP:
alCfg := &grpcaccesslog.TcpGrpcAccessLogConfig{
CommonConfig: cc,
}
- accesslogAny, _ := anypb.New(alCfg)
+ accesslogAny, err := protocov.ToAnyWithValidation(alCfg)
+ if err != nil {
+ return nil, err
+ }
accessLogs = append(accessLogs, &accesslog.AccessLog{
Name: tcpGRPCAccessLog,
ConfigType: &accesslog.AccessLog_TypedConfig{
TypedConfig: accesslogAny,
},
- Filter: buildAccessLogFilter(als.CELMatches, forListener),
+ Filter: buildAccessLogFilter(als.CELMatches, defaultLogTypeForListener),
})
}
}
// handle open telemetry access logs
for _, otel := range al.OpenTelemetry {
+ // Filter out logs that are not Global or match the desired access log type
+ if !(otel.LogType == nil || *otel.LogType == accessLogType) {
+ continue
+ }
+
+ // NR is only added to listener logs originating from a global log configuration
+ defaultLogTypeForListener := accessLogType == ir.ProxyAccessLogTypeListener && otel.LogType == nil
+
al := &otelaccesslog.OpenTelemetryAccessLogConfig{
CommonConfig: &grpcaccesslog.CommonGrpcAccessLogConfig{
LogName: otelLogName,
@@ -264,17 +306,20 @@ func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLo
al.Formatters = formatters
}
- accesslogAny, _ := anypb.New(al)
+ accesslogAny, err := protocov.ToAnyWithValidation(al)
+ if err != nil {
+ return nil, err
+ }
accessLogs = append(accessLogs, &accesslog.AccessLog{
Name: otelAccessLog,
ConfigType: &accesslog.AccessLog_TypedConfig{
TypedConfig: accesslogAny,
},
- Filter: buildAccessLogFilter(otel.CELMatches, forListener),
+ Filter: buildAccessLogFilter(otel.CELMatches, defaultLogTypeForListener),
})
}
- return accessLogs
+ return accessLogs, nil
}
func celAccessLogFilter(expr string) *accesslog.AccessLogFilter {
@@ -292,13 +337,13 @@ func celAccessLogFilter(expr string) *accesslog.AccessLogFilter {
}
}
-func buildAccessLogFilter(exprs []string, forListener bool) *accesslog.AccessLogFilter {
+func buildAccessLogFilter(exprs []string, withNoRouteMatchFilter bool) *accesslog.AccessLogFilter {
// add filter for access logs
var filters []*accesslog.AccessLogFilter
for _, expr := range exprs {
filters = append(filters, celAccessLogFilter(expr))
}
- if forListener {
+ if withNoRouteMatchFilter {
filters = append(filters, listenerAccessLogFilter)
}
@@ -478,28 +523,56 @@ func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessL
if al == nil {
return nil
}
-
// add clusters for ALS access logs
for _, als := range al.ALS {
+ traffic := als.Traffic
+ // Make sure that there are safe defaults for the traffic
+ if traffic == nil {
+ traffic = &ir.TrafficFeatures{}
+ }
if err := addXdsCluster(tCtx, &xdsClusterArgs{
- name: als.Destination.Name,
- settings: als.Destination.Settings,
- tSocket: nil,
- endpointType: EndpointTypeStatic,
- }); err != nil && !errors.Is(err, ErrXdsClusterExists) {
+ name: als.Destination.Name,
+ settings: als.Destination.Settings,
+ tSocket: nil,
+ endpointType: EndpointTypeStatic,
+ loadBalancer: traffic.LoadBalancer,
+ proxyProtocol: traffic.ProxyProtocol,
+ circuitBreaker: traffic.CircuitBreaker,
+ healthCheck: traffic.HealthCheck,
+ timeout: traffic.Timeout,
+ tcpkeepalive: traffic.TCPKeepalive,
+ backendConnection: traffic.BackendConnection,
+ dns: traffic.DNS,
+ http2Settings: traffic.HTTP2,
+ }); err != nil {
return err
}
}
// add clusters for Open Telemetry access logs
for _, otel := range al.OpenTelemetry {
+ traffic := otel.Traffic
+ // Make sure that there are safe defaults for the traffic
+ if traffic == nil {
+ traffic = &ir.TrafficFeatures{}
+ }
+
if err := addXdsCluster(tCtx, &xdsClusterArgs{
- name: otel.Destination.Name,
- settings: otel.Destination.Settings,
- tSocket: nil,
- endpointType: EndpointTypeDNS,
- metrics: metrics,
- }); err != nil && !errors.Is(err, ErrXdsClusterExists) {
+ name: otel.Destination.Name,
+ settings: otel.Destination.Settings,
+ tSocket: nil,
+ endpointType: EndpointTypeDNS,
+ metrics: metrics,
+ loadBalancer: traffic.LoadBalancer,
+ proxyProtocol: traffic.ProxyProtocol,
+ circuitBreaker: traffic.CircuitBreaker,
+ healthCheck: traffic.HealthCheck,
+ timeout: traffic.Timeout,
+ tcpkeepalive: traffic.TCPKeepalive,
+ backendConnection: traffic.BackendConnection,
+ dns: traffic.DNS,
+ http2Settings: traffic.HTTP2,
+ }); err != nil {
return err
}
}
diff --git a/internal/xds/translator/authorization.go b/internal/xds/translator/authorization.go
index e3a61b1641e..e19d1dbaf53 100644
--- a/internal/xds/translator/authorization.go
+++ b/internal/xds/translator/authorization.go
@@ -8,6 +8,7 @@ package translator
import (
"errors"
"fmt"
+ "strings"
cncfv3 "github.com/cncf/xds/go/xds/core/v3"
matcherv3 "github.com/cncf/xds/go/xds/type/matcher/v3"
@@ -18,11 +19,14 @@ import (
hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
networkinput "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/common_inputs/network/v3"
ipmatcherv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/input_matchers/ip/v3"
+ metadatav3 "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/input_matchers/metadata/v3"
+ envoymatcherv3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/wrapperspb"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils/protocov"
"github.com/envoyproxy/gateway/internal/xds/types"
)
@@ -72,7 +76,7 @@ func (*rbac) patchHCM(
// buildHCMRBACFilter returns a RBAC filter from the provided IR listener.
func buildHCMRBACFilter() (*hcmv3.HttpFilter, error) {
rbacProto := &rbacv3.RBAC{}
- rbacAny, err := anypb.New(rbacProto)
+ rbacAny, err := protocov.ToAnyWithValidation(rbacProto)
if err != nil {
return nil, err
}
@@ -121,29 +125,51 @@ func (*rbac) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
}
var (
- authorization = irRoute.Security.Authorization
- allowAction *anypb.Any
- denyAction *anypb.Any
- sourceIPInput *anypb.Any
- ipMatcher *anypb.Any
- matcherList []*matcherv3.Matcher_MatcherList_FieldMatcher
- err error
+ rbacPerRoute *rbacv3.RBACPerRoute
+ cfgAny *anypb.Any
+ err error
+ )
+
+ if rbacPerRoute, err = buildRBACPerRoute(irRoute.Security.Authorization); err != nil {
+ return err
+ }
+
+ if cfgAny, err = protocov.ToAnyWithValidation(rbacPerRoute); err != nil {
+ return err
+ }
+
+ if filterCfg == nil {
+ route.TypedPerFilterConfig = make(map[string]*anypb.Any)
+ }
+
+ route.TypedPerFilterConfig[egv1a1.EnvoyFilterRBAC.String()] = cfgAny
+
+ return nil
+}
+
+func buildRBACPerRoute(authorization *ir.Authorization) (*rbacv3.RBACPerRoute, error) {
+ var (
+ rbac *rbacv3.RBACPerRoute
+ allowAction *anypb.Any
+ denyAction *anypb.Any
+ matcherList []*matcherv3.Matcher_MatcherList_FieldMatcher
+ err error
)
allow := &rbacconfigv3.Action{
Name: "ALLOW",
Action: rbacconfigv3.RBAC_ALLOW,
}
- if allowAction, err = anypb.New(allow); err != nil {
- return err
+ if allowAction, err = protocov.ToAnyWithValidation(allow); err != nil {
+ return nil, err
}
deny := &rbacconfigv3.Action{
Name: "DENY",
Action: rbacconfigv3.RBAC_DENY,
}
- if denyAction, err = anypb.New(deny); err != nil {
- return err
+ if denyAction, err = protocov.ToAnyWithValidation(deny); err != nil {
+ return nil, err
}
// Build a list of matchers based on the rules.
@@ -152,52 +178,71 @@ func (*rbac) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
// skipped.
// If no matcher matches, the default action will be used.
for _, rule := range authorization.Rules {
- // Build the IPMatcher based on the client CIDRs.
- ipRangeMatcher := &ipmatcherv3.Ip{
- StatPrefix: "client_ip",
- }
+ var (
+ ipPredicate *matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_
+ jwtPredicate []*matcherv3.Matcher_MatcherList_Predicate
+ predicate *matcherv3.Matcher_MatcherList_Predicate
+ )
- for _, cidr := range rule.Principal.ClientCIDRs {
- ipRangeMatcher.CidrRanges = append(ipRangeMatcher.CidrRanges, &configv3.CidrRange{
- AddressPrefix: cidr.IP,
- PrefixLen: &wrapperspb.UInt32Value{
- Value: cidr.MaskLen,
- },
- })
+ // Determine the action for the current rule.
+ ruleAction := allowAction
+ if rule.Action == egv1a1.AuthorizationActionDeny {
+ ruleAction = denyAction
}
- if ipMatcher, err = anypb.New(ipRangeMatcher); err != nil {
- return err
+ if len(rule.Principal.ClientCIDRs) > 0 {
+ if ipPredicate, err = buildIPPredicate(rule.Principal.ClientCIDRs); err != nil {
+ return nil, err
+ }
}
- if sourceIPInput, err = anypb.New(&networkinput.SourceIPInput{}); err != nil {
- return err
+ if rule.Principal.JWT != nil {
+ if jwtPredicate, err = buildJWTPredicate(*rule.Principal.JWT); err != nil {
+ return nil, err
+ }
}
- // Determine the action for the current rule.
- ruleAction := allowAction
- if rule.Action == egv1a1.AuthorizationActionDeny {
- ruleAction = denyAction
+ // Build the predicate for the current rule.
+ switch {
+ // If both IP and JWT predicates are present, AND them together.
+ case ipPredicate != nil && jwtPredicate != nil:
+ predicates := []*matcherv3.Matcher_MatcherList_Predicate{
+ {
+ MatchType: ipPredicate,
+ },
+ }
+ predicates = append(predicates, jwtPredicate...)
+
+ predicate = &matcherv3.Matcher_MatcherList_Predicate{
+ MatchType: &matcherv3.Matcher_MatcherList_Predicate_AndMatcher{
+ AndMatcher: &matcherv3.Matcher_MatcherList_Predicate_PredicateList{
+ Predicate: predicates,
+ },
+ },
+ }
+ case ipPredicate != nil:
+ predicate = &matcherv3.Matcher_MatcherList_Predicate{
+ MatchType: ipPredicate,
+ }
+ case jwtPredicate != nil:
+ // If there are multiple JWT predicates, AND them together.
+ if len(jwtPredicate) > 1 {
+ predicate = &matcherv3.Matcher_MatcherList_Predicate{
+ MatchType: &matcherv3.Matcher_MatcherList_Predicate_AndMatcher{
+ AndMatcher: &matcherv3.Matcher_MatcherList_Predicate_PredicateList{
+ Predicate: jwtPredicate,
+ },
+ },
+ }
+ } else if len(jwtPredicate) == 1 {
+ predicate = jwtPredicate[0]
+ }
}
// Add the matcher generated with the current rule to the matcher list.
+ // The first matcher that matches will be used to determine the action.
matcherList = append(matcherList, &matcherv3.Matcher_MatcherList_FieldMatcher{
- Predicate: &matcherv3.Matcher_MatcherList_Predicate{
- MatchType: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_{
- SinglePredicate: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate{
- Input: &cncfv3.TypedExtensionConfig{
- Name: "client_ip",
- TypedConfig: sourceIPInput,
- },
- Matcher: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_CustomMatch{
- CustomMatch: &cncfv3.TypedExtensionConfig{
- Name: "ip_matcher",
- TypedConfig: ipMatcher,
- },
- },
- },
- },
- },
+ Predicate: predicate,
OnMatch: &matcherv3.Matcher_OnMatch{
OnMatch: &matcherv3.Matcher_OnMatch_Action{
Action: &cncfv3.TypedExtensionConfig{
@@ -215,7 +260,7 @@ func (*rbac) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
defaultAction = allowAction
}
- routeCfgProto := &rbacv3.RBACPerRoute{
+ rbac = &rbacv3.RBACPerRoute{
Rbac: &rbacv3.RBAC{
Matcher: &matcherv3.Matcher{
MatcherType: &matcherv3.Matcher_MatcherList_{
@@ -240,26 +285,255 @@ func (*rbac) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
// Setting the matcher type to nil since Proto validation will fail if the list
// is empty.
if len(matcherList) == 0 {
- routeCfgProto.Rbac.Matcher.MatcherType = nil
+ rbac.Rbac.Matcher.MatcherType = nil
}
- // We need to validate the RBACPerRoute message before converting it to an Any.
- if err = routeCfgProto.ValidateAll(); err != nil {
- return err
+ return rbac, nil
+}
+
+func buildIPPredicate(clientCIDRs []*ir.CIDRMatch) (*matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_, error) {
+ var (
+ sourceIPInput *anypb.Any
+ ipMatcher *anypb.Any
+ err error
+ )
+
+ // Build the IPMatcher based on the client CIDRs.
+ ipRangeMatcher := &ipmatcherv3.Ip{
+ StatPrefix: "client_ip",
}
- routeCfgAny, err := anypb.New(routeCfgProto)
- if err != nil {
- return err
+ for _, cidr := range clientCIDRs {
+ ipRangeMatcher.CidrRanges = append(ipRangeMatcher.CidrRanges, &configv3.CidrRange{
+ AddressPrefix: cidr.IP,
+ PrefixLen: &wrapperspb.UInt32Value{
+ Value: cidr.MaskLen,
+ },
+ })
}
- if filterCfg == nil {
- route.TypedPerFilterConfig = make(map[string]*anypb.Any)
+ if ipMatcher, err = protocov.ToAnyWithValidation(ipRangeMatcher); err != nil {
+ return nil, err
}
- route.TypedPerFilterConfig[egv1a1.EnvoyFilterRBAC.String()] = routeCfgAny
+ if sourceIPInput, err = protocov.ToAnyWithValidation(&networkinput.SourceIPInput{}); err != nil {
+ return nil, err
+ }
- return nil
+ return &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_{
+ SinglePredicate: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate{
+ Input: &cncfv3.TypedExtensionConfig{
+ Name: "client_ip",
+ TypedConfig: sourceIPInput,
+ },
+ Matcher: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_CustomMatch{
+ CustomMatch: &cncfv3.TypedExtensionConfig{
+ Name: "ip_matcher",
+ TypedConfig: ipMatcher,
+ },
+ },
+ },
+ }, nil
+}
+
+func buildJWTPredicate(jwt egv1a1.JWTPrincipal) ([]*matcherv3.Matcher_MatcherList_Predicate, error) {
+ jwtPredicate := []*matcherv3.Matcher_MatcherList_Predicate{}
+
+ // Build the scope matchers.
+ // Multiple scopes are ANDed together.
+ for _, scope := range jwt.Scopes {
+ var (
+ inputPb *anypb.Any
+ matcherPb *anypb.Any
+ err error
+ )
+
+ input := &networkinput.DynamicMetadataInput{
+ Filter: "envoy.filters.http.jwt_authn",
+ Path: []*networkinput.DynamicMetadataInput_PathSegment{
+ {
+ Segment: &networkinput.DynamicMetadataInput_PathSegment_Key{
+ Key: jwt.Provider, // The name of the jwt provider is used as the `payload_in_metadata` in the JWT Authn filter.
+ },
+ },
+ {
+ Segment: &networkinput.DynamicMetadataInput_PathSegment_Key{
+ Key: "scope",
+ },
+ },
+ },
+ }
+
+ // The scope has already been normalized to a string array in the JWT Authn filter.
+ scopeMatcher := &metadatav3.Metadata{
+ Value: &envoymatcherv3.ValueMatcher{
+ MatchPattern: &envoymatcherv3.ValueMatcher_ListMatch{
+ ListMatch: &envoymatcherv3.ListMatcher{
+ MatchPattern: &envoymatcherv3.ListMatcher_OneOf{
+ OneOf: &envoymatcherv3.ValueMatcher{
+ MatchPattern: &envoymatcherv3.ValueMatcher_StringMatch{
+ StringMatch: &envoymatcherv3.StringMatcher{
+ MatchPattern: &envoymatcherv3.StringMatcher_Exact{
+ Exact: string(scope),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+
+ if inputPb, err = protocov.ToAnyWithValidation(input); err != nil {
+ return nil, err
+ }
+
+ if matcherPb, err = protocov.ToAnyWithValidation(scopeMatcher); err != nil {
+ return nil, err
+ }
+
+ scopePredicate := matcherv3.Matcher_MatcherList_Predicate_SinglePredicate{
+ Input: &cncfv3.TypedExtensionConfig{
+ Name: "scope",
+ TypedConfig: inputPb,
+ },
+ Matcher: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_CustomMatch{
+ CustomMatch: &cncfv3.TypedExtensionConfig{
+ Name: "scope_matcher",
+ TypedConfig: matcherPb,
+ },
+ },
+ }
+
+ jwtPredicate = append(jwtPredicate,
+ &matcherv3.Matcher_MatcherList_Predicate{
+ MatchType: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_{
+ SinglePredicate: &scopePredicate,
+ },
+ },
+ )
+ }
+
+ // Build the claim matchers.
+ // Multiple claims are ANDed together.
+ // Multiple values for a claim are ORed together.
+ // For example, if we have two claims: "claim1" with values ["value1", "value2"], and "claim2" with values ["value3", "value4"],
+ // the resulting matcher will be: (claim1 == value1 OR claim1 == value2) AND (claim2 == value3 OR claim2 == value4).
+ predicateForAllClaims := []*matcherv3.Matcher_MatcherList_Predicate{}
+ for _, claim := range jwt.Claims {
+ var (
+ inputPb *anypb.Any
+ matcherPb *anypb.Any
+ err error
+ )
+
+ path := []*networkinput.DynamicMetadataInput_PathSegment{
+ {
+ Segment: &networkinput.DynamicMetadataInput_PathSegment_Key{
+ Key: jwt.Provider, // The name of the jwt provider is used as the `payload_in_metadata` in the JWT Authn filter.
+ },
+ },
+ }
+
+ // A nested claim is represented as a dot-separated string, e.g., "user.email".
+ for _, segment := range strings.Split(claim.Name, ".") {
+ path = append(path, &networkinput.DynamicMetadataInput_PathSegment{
+ Segment: &networkinput.DynamicMetadataInput_PathSegment_Key{
+ Key: segment,
+ },
+ })
+ }
+
+ input := &networkinput.DynamicMetadataInput{
+ Filter: "envoy.filters.http.jwt_authn",
+ Path: path,
+ }
+
+ if inputPb, err = protocov.ToAnyWithValidation(input); err != nil {
+ return nil, err
+ }
+
+ predicateForOneClaim := []*matcherv3.Matcher_MatcherList_Predicate{}
+ for _, value := range claim.Values {
+ var valueMatcher *envoymatcherv3.ValueMatcher
+
+ if claim.ValueType != nil && *claim.ValueType == egv1a1.JWTClaimValueTypeStringArray {
+ valueMatcher = &envoymatcherv3.ValueMatcher{
+ MatchPattern: &envoymatcherv3.ValueMatcher_ListMatch{
+ ListMatch: &envoymatcherv3.ListMatcher{
+ MatchPattern: &envoymatcherv3.ListMatcher_OneOf{
+ OneOf: &envoymatcherv3.ValueMatcher{
+ MatchPattern: &envoymatcherv3.ValueMatcher_StringMatch{
+ StringMatch: &envoymatcherv3.StringMatcher{
+ MatchPattern: &envoymatcherv3.StringMatcher_Exact{
+ Exact: value,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ } else {
+ valueMatcher = &envoymatcherv3.ValueMatcher{
+ MatchPattern: &envoymatcherv3.ValueMatcher_StringMatch{
+ StringMatch: &envoymatcherv3.StringMatcher{
+ MatchPattern: &envoymatcherv3.StringMatcher_Exact{
+ Exact: value,
+ },
+ },
+ },
+ }
+ }
+
+ if matcherPb, err = protocov.ToAnyWithValidation(&metadatav3.Metadata{
+ Value: valueMatcher,
+ }); err != nil {
+ return nil, err
+ }
+
+ predicateForOneClaim = append(predicateForOneClaim, &matcherv3.Matcher_MatcherList_Predicate{
+ MatchType: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_{
+ SinglePredicate: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate{
+ Input: &cncfv3.TypedExtensionConfig{
+ Name: "claim",
+ TypedConfig: inputPb,
+ },
+ Matcher: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_CustomMatch{
+ CustomMatch: &cncfv3.TypedExtensionConfig{
+ Name: "claim_matcher",
+ TypedConfig: matcherPb,
+ },
+ },
+ },
+ },
+ })
+ }
+
+ // For a claim to match, one of the values must match.
+ // If there are multiple values for a claim, OR them together.
+ if len(predicateForOneClaim) > 1 {
+ predicateForAllClaims = append(predicateForAllClaims, &matcherv3.Matcher_MatcherList_Predicate{
+ MatchType: &matcherv3.Matcher_MatcherList_Predicate_OrMatcher{
+ OrMatcher: &matcherv3.Matcher_MatcherList_Predicate_PredicateList{
+ Predicate: predicateForOneClaim,
+ },
+ },
+ })
+ } else if len(predicateForOneClaim) == 1 {
+ predicateForAllClaims = append(predicateForAllClaims, &matcherv3.Matcher_MatcherList_Predicate{
+ MatchType: predicateForOneClaim[0].MatchType.(*matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_),
+ })
+ }
+ }
+
+ // For a JWT principal to match, all the specified claims and scopes must match.
+ // And all the claims and scopes together.
+ jwtPredicate = append(jwtPredicate, predicateForAllClaims...)
+
+ return jwtPredicate, nil
}
func (c *rbac) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error {
diff --git a/internal/xds/translator/basicauth.go b/internal/xds/translator/basicauth.go
index 50c4935140b..31a421ae8a9 100644
--- a/internal/xds/translator/basicauth.go
+++ b/internal/xds/translator/basicauth.go
@@ -17,6 +17,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils/protocov"
"github.com/envoyproxy/gateway/internal/xds/types"
)
@@ -84,7 +85,7 @@ func buildHCMBasicAuthFilter(basicAuth *ir.BasicAuth) (*hcmv3.HttpFilter, error)
if err = basicAuthProto.ValidateAll(); err != nil {
return nil, err
}
- if basicAuthAny, err = anypb.New(basicAuthProto); err != nil {
+ if basicAuthAny, err = protocov.ToAnyWithValidation(basicAuthProto); err != nil {
return nil, err
}
@@ -134,7 +135,7 @@ func (*basicAuth) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error
return err
}
- if basicAuthAny, err = anypb.New(basicAuthProto); err != nil {
+ if basicAuthAny, err = protocov.ToAnyWithValidation(basicAuthProto); err != nil {
return err
}
diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go
index e646f410944..eadb00fb56f 100644
--- a/internal/xds/translator/cluster.go
+++ b/internal/xds/translator/cluster.go
@@ -28,7 +28,9 @@ import (
"google.golang.org/protobuf/types/known/wrapperspb"
"k8s.io/utils/ptr"
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils/protocov"
)
const (
@@ -48,11 +50,14 @@ type xdsClusterArgs struct {
circuitBreaker *ir.CircuitBreaker
healthCheck *ir.HealthCheck
http1Settings *ir.HTTP1Settings
+ http2Settings *ir.HTTP2Settings
timeout *ir.Timeout
tcpkeepalive *ir.TCPKeepalive
metrics *ir.Metrics
backendConnection *ir.BackendConnection
+ dns *ir.DNS
useClientProtocol bool
+ ipFamily *egv1a1.IPFamily
}
type EndpointType int
@@ -79,23 +84,42 @@ func buildEndpointType(settings []*ir.DestinationSetting) EndpointType {
}
func buildXdsCluster(args *xdsClusterArgs) *clusterv3.Cluster {
+ dnsLookupFamily := clusterv3.Cluster_V4_PREFERRED
+ if args.ipFamily != nil {
+ switch *args.ipFamily {
+ case egv1a1.IPv4:
+ dnsLookupFamily = clusterv3.Cluster_V4_ONLY
+ case egv1a1.IPv6:
+ dnsLookupFamily = clusterv3.Cluster_V6_ONLY
+ case egv1a1.DualStack:
+ dnsLookupFamily = clusterv3.Cluster_ALL
+ }
+ }
cluster := &clusterv3.Cluster{
Name: args.name,
- DnsLookupFamily: clusterv3.Cluster_V4_ONLY,
+ DnsLookupFamily: dnsLookupFamily,
CommonLbConfig: &clusterv3.Cluster_CommonLbConfig{
LocalityConfigSpecifier: &clusterv3.Cluster_CommonLbConfig_LocalityWeightedLbConfig_{
LocalityWeightedLbConfig: &clusterv3.Cluster_CommonLbConfig_LocalityWeightedLbConfig{},
},
},
- OutlierDetection: &clusterv3.OutlierDetection{},
PerConnectionBufferLimitBytes: buildBackandConnectionBufferLimitBytes(args.backendConnection),
}
cluster.ConnectTimeout = buildConnectTimeout(args.timeout)
- // set peer endpoint stats
- if args.metrics != nil && args.metrics.EnablePerEndpointStats {
- cluster.TrackClusterStats = &clusterv3.TrackClusterStats{
- PerEndpointStats: args.metrics.EnablePerEndpointStats,
+
+ // Initialize TrackClusterStats if any metrics are enabled
+ if args.metrics != nil && (args.metrics.EnablePerEndpointStats || args.metrics.EnableRequestResponseSizesStats) {
+ cluster.TrackClusterStats = &clusterv3.TrackClusterStats{}
+
+ // Set per endpoint stats if enabled
+ if args.metrics.EnablePerEndpointStats {
+ cluster.TrackClusterStats.PerEndpointStats = args.metrics.EnablePerEndpointStats
+ }
+
+ // Set request response sizes stats if enabled
+ if args.metrics.EnableRequestResponseSizesStats {
+ cluster.TrackClusterStats.RequestResponseSizes = args.metrics.EnableRequestResponseSizesStats
}
}
@@ -140,10 +164,23 @@ func buildXdsCluster(args *xdsClusterArgs) *clusterv3.Cluster {
},
},
}
+ // Dont wait for a health check to determine health and remove these endpoints
+ // if the endpoint has been removed via EDS by the control plane
+ cluster.IgnoreHealthOnHostRemoval = true
} else {
cluster.ClusterDiscoveryType = &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STRICT_DNS}
cluster.DnsRefreshRate = durationpb.New(30 * time.Second)
cluster.RespectDnsTtl = true
+ if args.dns != nil {
+ if args.dns.DNSRefreshRate != nil {
+ if args.dns.DNSRefreshRate.Duration > 0 {
+ cluster.DnsRefreshRate = durationpb.New(args.dns.DNSRefreshRate.Duration)
+ }
+ }
+ if args.dns.RespectDNSTTL != nil {
+ cluster.RespectDnsTtl = ptr.Deref(args.dns.RespectDNSTTL, true)
+ }
+ }
}
// build common, HTTP/1 and HTTP/2 protocol options for cluster
@@ -171,15 +208,13 @@ func buildXdsCluster(args *xdsClusterArgs) *clusterv3.Cluster {
}
} else if args.loadBalancer.RoundRobin != nil {
cluster.LbPolicy = clusterv3.Cluster_ROUND_ROBIN
- if args.loadBalancer.RoundRobin.SlowStart != nil {
- if args.loadBalancer.RoundRobin.SlowStart.Window != nil {
- cluster.LbConfig = &clusterv3.Cluster_RoundRobinLbConfig_{
- RoundRobinLbConfig: &clusterv3.Cluster_RoundRobinLbConfig{
- SlowStartConfig: &clusterv3.Cluster_SlowStartConfig{
- SlowStartWindow: durationpb.New(args.loadBalancer.RoundRobin.SlowStart.Window.Duration),
- },
+ if args.loadBalancer.RoundRobin.SlowStart != nil && args.loadBalancer.RoundRobin.SlowStart.Window != nil {
+ cluster.LbConfig = &clusterv3.Cluster_RoundRobinLbConfig_{
+ RoundRobinLbConfig: &clusterv3.Cluster_RoundRobinLbConfig{
+ SlowStartConfig: &clusterv3.Cluster_SlowStartConfig{
+ SlowStartWindow: durationpb.New(args.loadBalancer.RoundRobin.SlowStart.Window.Duration),
},
- }
+ },
}
}
} else if args.loadBalancer.Random != nil {
@@ -223,7 +258,8 @@ func buildXdsHealthCheck(healthcheck *ir.ActiveHealthCheck) []*corev3.HealthChec
if healthcheck.HealthyThreshold != nil {
hc.HealthyThreshold = wrapperspb.UInt32(*healthcheck.HealthyThreshold)
}
- if healthcheck.HTTP != nil {
+ switch {
+ case healthcheck.HTTP != nil:
httpChecker := &corev3.HealthCheck_HttpHealthCheck{
Host: healthcheck.HTTP.Host,
Path: healthcheck.HTTP.Path,
@@ -238,8 +274,7 @@ func buildXdsHealthCheck(healthcheck *ir.ActiveHealthCheck) []*corev3.HealthChec
hc.HealthChecker = &corev3.HealthCheck_HttpHealthCheck_{
HttpHealthCheck: httpChecker,
}
- }
- if healthcheck.TCP != nil {
+ case healthcheck.TCP != nil:
tcpChecker := &corev3.HealthCheck_TcpHealthCheck{
Send: buildHealthCheckPayload(healthcheck.TCP.Send),
}
@@ -249,6 +284,12 @@ func buildXdsHealthCheck(healthcheck *ir.ActiveHealthCheck) []*corev3.HealthChec
hc.HealthChecker = &corev3.HealthCheck_TcpHealthCheck_{
TcpHealthCheck: tcpChecker,
}
+ case healthcheck.GRPC != nil:
+ hc.HealthChecker = &corev3.HealthCheck_GrpcHealthCheck_{
+ GrpcHealthCheck: &corev3.HealthCheck_GrpcHealthCheck{
+ ServiceName: ptr.Deref(healthcheck.GRPC.Service, ""),
+ },
+ }
}
return []*corev3.HealthCheck{hc}
}
@@ -426,7 +467,7 @@ func buildXdsClusterLoadAssignment(clusterName string, destSettings []*ir.Destin
weight = 1
}
locality.LoadBalancingWeight = &wrapperspb.UInt32Value{Value: weight}
-
+ locality.Priority = ptr.Deref(ds.Priority, 0)
localities = append(localities, locality)
}
return &endpointv3.ClusterLoadAssignment{ClusterName: clusterName, Endpoints: localities}
@@ -478,7 +519,7 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb.
if args.http1Settings != nil {
http1opts.EnableTrailers = args.http1Settings.EnableTrailers
if args.http1Settings.PreserveHeaderCase {
- preservecaseAny, _ := anypb.New(&preservecasev3.PreserveCaseFormatterConfig{})
+ preservecaseAny, _ := protocov.ToAnyWithValidation(&preservecasev3.PreserveCaseFormatterConfig{})
http1opts.HeaderKeyFormat = &corev3.Http1ProtocolOptions_HeaderKeyFormat{
HeaderFormat: &corev3.Http1ProtocolOptions_HeaderKeyFormat_StatefulFormatter{
StatefulFormatter: &corev3.TypedExtensionConfig{
@@ -504,13 +545,15 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb.
protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_UseDownstreamProtocolConfig{
UseDownstreamProtocolConfig: &httpv3.HttpProtocolOptions_UseDownstreamHttpConfig{
HttpProtocolOptions: http1opts,
- Http2ProtocolOptions: &corev3.Http2ProtocolOptions{},
+ Http2ProtocolOptions: buildHTTP2Settings(args.http2Settings),
},
}
case requiresHTTP2Options:
protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_ExplicitHttpConfig_{
ExplicitHttpConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig{
- ProtocolConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{},
+ ProtocolConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{
+ Http2ProtocolOptions: buildHTTP2Settings(args.http2Settings),
+ },
},
}
case requiresHTTP1Options:
@@ -529,7 +572,7 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb.
}
}
- anyProtocolOptions, _ := anypb.New(&protocolOptions)
+ anyProtocolOptions, _ := protocov.ToAnyWithValidation(&protocolOptions)
extensionOptions := map[string]*anypb.Any{
extensionOptionsKey: anyProtocolOptions,
@@ -560,7 +603,7 @@ func buildProxyProtocolSocket(proxyProtocol *ir.ProxyProtocol, tSocket *corev3.T
// If existing transport socket does not exist wrap around raw buffer
if tSocket == nil {
rawCtx := &rawbufferv3.RawBuffer{}
- rawCtxAny, err := anypb.New(rawCtx)
+ rawCtxAny, err := protocov.ToAnyWithValidation(rawCtx)
if err != nil {
return nil
}
@@ -575,7 +618,7 @@ func buildProxyProtocolSocket(proxyProtocol *ir.ProxyProtocol, tSocket *corev3.T
ppCtx.TransportSocket = tSocket
}
- ppCtxAny, err := anypb.New(ppCtx)
+ ppCtxAny, err := protocov.ToAnyWithValidation(ppCtx)
if err != nil {
return nil
}
@@ -649,3 +692,115 @@ func buildBackandConnectionBufferLimitBytes(bc *ir.BackendConnection) *wrappers.
return wrapperspb.UInt32(tcpClusterPerConnectionBufferLimitBytes)
}
+
+type ExtraArgs struct {
+ metrics *ir.Metrics
+ http1Settings *ir.HTTP1Settings
+ http2Settings *ir.HTTP2Settings
+ ipFamily *egv1a1.IPFamily
+}
+
+type clusterArgs interface {
+ asClusterArgs(extras *ExtraArgs) *xdsClusterArgs
+}
+
+type UDPRouteTranslator struct {
+ *ir.UDPRoute
+}
+
+func (route *UDPRouteTranslator) asClusterArgs(extra *ExtraArgs) *xdsClusterArgs {
+ return &xdsClusterArgs{
+ name: route.Destination.Name,
+ settings: route.Destination.Settings,
+ loadBalancer: route.LoadBalancer,
+ endpointType: buildEndpointType(route.Destination.Settings),
+ metrics: extra.metrics,
+ dns: route.DNS,
+ ipFamily: extra.ipFamily,
+ }
+}
+
+type TCPRouteTranslator struct {
+ *ir.TCPRoute
+}
+
+func (route *TCPRouteTranslator) asClusterArgs(extra *ExtraArgs) *xdsClusterArgs {
+ return &xdsClusterArgs{
+ name: route.Destination.Name,
+ settings: route.Destination.Settings,
+ loadBalancer: route.LoadBalancer,
+ proxyProtocol: route.ProxyProtocol,
+ circuitBreaker: route.CircuitBreaker,
+ tcpkeepalive: route.TCPKeepalive,
+ healthCheck: route.HealthCheck,
+ timeout: route.Timeout,
+ endpointType: buildEndpointType(route.Destination.Settings),
+ metrics: extra.metrics,
+ backendConnection: route.BackendConnection,
+ dns: route.DNS,
+ ipFamily: extra.ipFamily,
+ }
+}
+
+type HTTPRouteTranslator struct {
+ *ir.HTTPRoute
+}
+
+func (httpRoute *HTTPRouteTranslator) asClusterArgs(extra *ExtraArgs) *xdsClusterArgs {
+ clusterArgs := &xdsClusterArgs{
+ name: httpRoute.Destination.Name,
+ settings: httpRoute.Destination.Settings,
+ tSocket: nil,
+ endpointType: buildEndpointType(httpRoute.Destination.Settings),
+ metrics: extra.metrics,
+ http1Settings: extra.http1Settings,
+ http2Settings: extra.http2Settings,
+ useClientProtocol: ptr.Deref(httpRoute.UseClientProtocol, false),
+ ipFamily: extra.ipFamily,
+ }
+
+ // Populate traffic features.
+ bt := httpRoute.Traffic
+ if bt != nil {
+ clusterArgs.loadBalancer = bt.LoadBalancer
+ clusterArgs.proxyProtocol = bt.ProxyProtocol
+ clusterArgs.circuitBreaker = bt.CircuitBreaker
+ clusterArgs.healthCheck = bt.HealthCheck
+ clusterArgs.timeout = bt.Timeout
+ clusterArgs.tcpkeepalive = bt.TCPKeepalive
+ clusterArgs.backendConnection = bt.BackendConnection
+ clusterArgs.dns = bt.DNS
+ }
+
+ return clusterArgs
+}
+
+func buildHTTP2Settings(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions {
+ if opts == nil {
+ opts = &ir.HTTP2Settings{}
+ }
+
+ // defaults based on https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge
+ out := &corev3.Http2ProtocolOptions{
+ InitialStreamWindowSize: &wrapperspb.UInt32Value{
+ Value: ptr.Deref(opts.InitialStreamWindowSize, http2InitialStreamWindowSize),
+ },
+ InitialConnectionWindowSize: &wrapperspb.UInt32Value{
+ Value: ptr.Deref(opts.InitialConnectionWindowSize, http2InitialConnectionWindowSize),
+ },
+ }
+
+ if opts.MaxConcurrentStreams != nil {
+ out.MaxConcurrentStreams = &wrapperspb.UInt32Value{
+ Value: *opts.MaxConcurrentStreams,
+ }
+ }
+
+ if opts.ResetStreamOnError != nil {
+ out.OverrideStreamErrorOnInvalidHttpMessage = &wrapperspb.BoolValue{
+ Value: *opts.ResetStreamOnError,
+ }
+ }
+
+ return out
+}
diff --git a/internal/xds/translator/cors.go b/internal/xds/translator/cors.go
index cda5ae8a40a..542b9aa680c 100644
--- a/internal/xds/translator/cors.go
+++ b/internal/xds/translator/cors.go
@@ -134,8 +134,18 @@ func (*cors) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
allowOrigins = append(allowOrigins, buildXdsStringMatcher(origin))
}
- allowMethods = strings.Join(c.AllowMethods, ", ")
- allowHeaders = strings.Join(c.AllowHeaders, ", ")
+ // Envoy only supports a single "*" for matching all, and treats the "*" in "*, GET" as a literal.
+ // https://github.com/envoyproxy/envoy/blob/eb61f368690cae173502f80549b7e2169ec24766/source/extensions/filters/http/cors/cors_filter.cc#L140-L159
+ if hasWildcard(c.AllowMethods) {
+ allowMethods = "*"
+ } else {
+ allowMethods = strings.Join(c.AllowMethods, ", ")
+ }
+ if hasWildcard(c.AllowHeaders) {
+ allowHeaders = "*"
+ } else {
+ allowHeaders = strings.Join(c.AllowHeaders, ", ")
+ }
exposeHeaders = strings.Join(c.ExposeHeaders, ", ")
if c.MaxAge != nil {
maxAge = strconv.Itoa(int(c.MaxAge.Seconds()))
@@ -166,6 +176,15 @@ func (*cors) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
return nil
}
+func hasWildcard(array []string) bool {
+ for _, s := range array {
+ if s == "*" {
+ return true
+ }
+ }
+ return false
+}
+
func (c *cors) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error {
return nil
}
diff --git a/internal/xds/translator/custom_response.go b/internal/xds/translator/custom_response.go
new file mode 100644
index 00000000000..6cca67982e9
--- /dev/null
+++ b/internal/xds/translator/custom_response.go
@@ -0,0 +1,452 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package translator
+
+import (
+ "errors"
+ "fmt"
+ "strconv"
+
+ cncfv3 "github.com/cncf/xds/go/xds/core/v3"
+ matcherv3 "github.com/cncf/xds/go/xds/type/matcher/v3"
+ typev3 "github.com/cncf/xds/go/xds/type/v3"
+ corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
+ routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
+ respv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/custom_response/v3"
+ hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
+ policyv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/custom_response/local_response_policy/v3"
+ envoymatcherv3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
+ expr "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
+ "google.golang.org/protobuf/types/known/anypb"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils/protocov"
+ "github.com/envoyproxy/gateway/internal/xds/types"
+)
+
+func init() {
+ registerHTTPFilter(&customResponse{})
+}
+
+type customResponse struct{}
+
+var _ httpFilter = &customResponse{}
+
+// patchHCM builds and appends the customResponse Filters to the HTTP Connection Manager
+// if applicable, and it does not already exist.
+// Note: this method creates an customResponse filter for each route that contains an ResponseOverride config.
+// the filter is disabled by default. It is enabled on the route level.
+func (c *customResponse) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error {
+ var errs error
+
+ if mgr == nil {
+ return errors.New("hcm is nil")
+ }
+
+ if irListener == nil {
+ return errors.New("ir listener is nil")
+ }
+
+ for _, route := range irListener.Routes {
+ if !c.routeContainsResponseOverride(route) {
+ continue
+ }
+
+ // Only generates one CustomResponse Envoy filter for each unique name.
+ // For example, if there are two routes under the same gateway with the
+ // same CustomResponse config, only one CustomResponse filter will be generated.
+ if hcmContainsFilter(mgr, c.customResponseFilterName(route.Traffic.ResponseOverride)) {
+ continue
+ }
+
+ filter, err := c.buildHCMCustomResponseFilter(route.Traffic.ResponseOverride)
+ if err != nil {
+ errs = errors.Join(errs, err)
+ continue
+ }
+
+ mgr.HttpFilters = append(mgr.HttpFilters, filter)
+ }
+
+ return errs
+}
+
+// buildHCMCustomResponseFilter returns an OAuth2 HTTP filter from the provided IR HTTPRoute.
+func (c *customResponse) buildHCMCustomResponseFilter(ro *ir.ResponseOverride) (*hcmv3.HttpFilter, error) {
+ proto, err := c.customResponseConfig(ro)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := proto.ValidateAll(); err != nil {
+ return nil, err
+ }
+
+ any, err := protocov.ToAnyWithValidation(proto)
+ if err != nil {
+ return nil, err
+ }
+
+ return &hcmv3.HttpFilter{
+ Name: c.customResponseFilterName(ro),
+ Disabled: true,
+ ConfigType: &hcmv3.HttpFilter_TypedConfig{
+ TypedConfig: any,
+ },
+ }, nil
+}
+
+func (c *customResponse) customResponseFilterName(ro *ir.ResponseOverride) string {
+ return perRouteFilterName(egv1a1.EnvoyFilterCustomResponse, ro.Name)
+}
+
+func (c *customResponse) customResponseConfig(ro *ir.ResponseOverride) (*respv3.CustomResponse, error) {
+ var matchers []*matcherv3.Matcher_MatcherList_FieldMatcher
+
+ for _, r := range ro.Rules {
+ var (
+ action *matcherv3.Matcher_OnMatch_Action
+ predicate *matcherv3.Matcher_MatcherList_Predicate
+ err error
+ )
+
+ if action, err = c.buildAction(r); err != nil {
+ return nil, err
+ }
+
+ switch {
+ case len(r.Match.StatusCodes) == 0:
+ // This is just a sanity check, as the CRD validation should have caught this.
+ return nil, fmt.Errorf("missing status code in response override rule")
+ case len(r.Match.StatusCodes) == 1:
+ if predicate, err = c.buildSinglePredicate(r.Match.StatusCodes[0]); err != nil {
+ return nil, err
+ }
+
+ matcher := &matcherv3.Matcher_MatcherList_FieldMatcher{
+ Predicate: predicate,
+ OnMatch: &matcherv3.Matcher_OnMatch{
+ OnMatch: action,
+ },
+ }
+
+ matchers = append(matchers, matcher)
+ case len(r.Match.StatusCodes) > 1:
+ var predicates []*matcherv3.Matcher_MatcherList_Predicate
+
+ for _, codeMatch := range r.Match.StatusCodes {
+ if predicate, err = c.buildSinglePredicate(codeMatch); err != nil {
+ return nil, err
+ }
+
+ predicates = append(predicates, predicate)
+ }
+
+ // Create a single matcher that ORs all the predicates together.
+ // The rule will match if any of the codes match.
+ matcher := &matcherv3.Matcher_MatcherList_FieldMatcher{
+ Predicate: &matcherv3.Matcher_MatcherList_Predicate{
+ MatchType: &matcherv3.Matcher_MatcherList_Predicate_OrMatcher{
+ OrMatcher: &matcherv3.Matcher_MatcherList_Predicate_PredicateList{
+ Predicate: predicates,
+ },
+ },
+ },
+ OnMatch: &matcherv3.Matcher_OnMatch{
+ OnMatch: action,
+ },
+ }
+
+ matchers = append(matchers, matcher)
+ }
+
+ }
+
+ // Create a MatcherList.
+ // The rules will be evaluated in order, and the first match wins.
+ cr := &respv3.CustomResponse{
+ CustomResponseMatcher: &matcherv3.Matcher{
+ MatcherType: &matcherv3.Matcher_MatcherList_{
+ MatcherList: &matcherv3.Matcher_MatcherList{
+ Matchers: matchers,
+ },
+ },
+ },
+ }
+
+ return cr, nil
+}
+
+func (c *customResponse) buildSinglePredicate(codeMatch ir.StatusCodeMatch) (*matcherv3.Matcher_MatcherList_Predicate, error) {
+ var (
+ httpAttributeCELInput *cncfv3.TypedExtensionConfig
+ statusCodeInput *cncfv3.TypedExtensionConfig
+ statusCodeCELMatcher *cncfv3.TypedExtensionConfig
+ err error
+ )
+
+ // Use CEL to match a range of status codes.
+ if codeMatch.Range != nil {
+ if httpAttributeCELInput, err = c.buildHTTPAttributeCELInput(); err != nil {
+ return nil, err
+ }
+
+ if statusCodeCELMatcher, err = c.buildStatusCodeCELMatcher(*codeMatch.Range); err != nil {
+ return nil, err
+ }
+
+ return &matcherv3.Matcher_MatcherList_Predicate{
+ MatchType: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_{
+ SinglePredicate: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate{
+ Input: httpAttributeCELInput,
+ Matcher: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_CustomMatch{
+ CustomMatch: statusCodeCELMatcher,
+ },
+ },
+ },
+ }, nil
+ } else {
+ // Use exact string match to match a single status code.
+ if statusCodeInput, err = c.buildStatusCodeInput(); err != nil {
+ return nil, err
+ }
+
+ return &matcherv3.Matcher_MatcherList_Predicate{
+ MatchType: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_{
+ SinglePredicate: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate{
+ Input: statusCodeInput,
+ Matcher: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_ValueMatch{
+ ValueMatch: &matcherv3.StringMatcher{
+ MatchPattern: &matcherv3.StringMatcher_Exact{
+ Exact: strconv.Itoa(*codeMatch.Value),
+ },
+ },
+ },
+ },
+ },
+ }, nil
+ }
+}
+
+func (c *customResponse) buildHTTPAttributeCELInput() (*cncfv3.TypedExtensionConfig, error) {
+ var (
+ pb *anypb.Any
+ err error
+ )
+
+ if pb, err = protocov.ToAnyWithValidation(&matcherv3.HttpAttributesCelMatchInput{}); err != nil {
+ return nil, err
+ }
+
+ return &cncfv3.TypedExtensionConfig{
+ Name: "http-attributes-cel-match-input",
+ TypedConfig: pb,
+ }, nil
+}
+
+func (c *customResponse) buildStatusCodeInput() (*cncfv3.TypedExtensionConfig, error) {
+ var (
+ pb *anypb.Any
+ err error
+ )
+
+ if pb, err = protocov.ToAnyWithValidation(&envoymatcherv3.HttpResponseStatusCodeMatchInput{}); err != nil {
+ return nil, err
+ }
+
+ return &cncfv3.TypedExtensionConfig{
+ Name: "http-response-status-code-match-input",
+ TypedConfig: pb,
+ }, nil
+}
+
+func (c *customResponse) buildStatusCodeCELMatcher(codeRange ir.StatusCodeRange) (*cncfv3.TypedExtensionConfig, error) {
+ var (
+ pb *anypb.Any
+ err error
+ )
+
+ // Build the CEL expression AST: response.code >= codeRange.Start && response.code <= codeRange.End
+ matcher := &matcherv3.CelMatcher{
+ ExprMatch: &typev3.CelExpression{
+ ExprSpecifier: &typev3.CelExpression_ParsedExpr{
+ ParsedExpr: &expr.ParsedExpr{
+ Expr: &expr.Expr{
+ Id: 9,
+ ExprKind: &expr.Expr_CallExpr{
+ CallExpr: &expr.Expr_Call{
+ Function: "_&&_",
+ Args: []*expr.Expr{
+ {
+ Id: 3,
+ ExprKind: &expr.Expr_CallExpr{
+ CallExpr: &expr.Expr_Call{
+ Function: "_>=_",
+ Args: []*expr.Expr{
+ {
+ Id: 2,
+ ExprKind: &expr.Expr_SelectExpr{
+ SelectExpr: &expr.Expr_Select{
+ Operand: &expr.Expr{
+ Id: 1,
+ ExprKind: &expr.Expr_IdentExpr{
+ IdentExpr: &expr.Expr_Ident{
+ Name: "response",
+ },
+ },
+ },
+ Field: "code",
+ },
+ },
+ },
+ {
+ Id: 4,
+ ExprKind: &expr.Expr_ConstExpr{
+ ConstExpr: &expr.Constant{
+ ConstantKind: &expr.Constant_Int64Value{
+ Int64Value: int64(codeRange.Start),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ Id: 7,
+ ExprKind: &expr.Expr_CallExpr{
+ CallExpr: &expr.Expr_Call{
+ Function: "_<=_",
+ Args: []*expr.Expr{
+ {
+ Id: 6,
+ ExprKind: &expr.Expr_SelectExpr{
+ SelectExpr: &expr.Expr_Select{
+ Operand: &expr.Expr{
+ Id: 5,
+ ExprKind: &expr.Expr_IdentExpr{
+ IdentExpr: &expr.Expr_Ident{
+ Name: "response",
+ },
+ },
+ },
+ Field: "code",
+ },
+ },
+ },
+ {
+ Id: 8,
+ ExprKind: &expr.Expr_ConstExpr{
+ ConstExpr: &expr.Constant{
+ ConstantKind: &expr.Constant_Int64Value{
+ Int64Value: int64(codeRange.End),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ if err := matcher.ValidateAll(); err != nil {
+ return nil, err
+ }
+
+ if pb, err = protocov.ToAnyWithValidation(matcher); err != nil {
+ return nil, err
+ }
+
+ return &cncfv3.TypedExtensionConfig{
+ Name: "cel-matcher",
+ TypedConfig: pb,
+ }, nil
+}
+
+func (c *customResponse) buildAction(r ir.ResponseOverrideRule) (*matcherv3.Matcher_OnMatch_Action, error) {
+ response := &policyv3.LocalResponsePolicy{}
+ if r.Response.Body != nil && *r.Response.Body != "" {
+ response.Body = &corev3.DataSource{
+ Specifier: &corev3.DataSource_InlineString{
+ InlineString: *r.Response.Body,
+ },
+ }
+ }
+
+ if r.Response.ContentType != nil && *r.Response.ContentType != "" {
+ response.ResponseHeadersToAdd = append(response.ResponseHeadersToAdd, &corev3.HeaderValueOption{
+ Header: &corev3.HeaderValue{
+ Key: "Content-Type",
+ Value: *r.Response.ContentType,
+ },
+ AppendAction: corev3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
+ })
+ }
+
+ var (
+ pb *anypb.Any
+ err error
+ )
+
+ if err := response.ValidateAll(); err != nil {
+ return nil, err
+ }
+
+ if pb, err = protocov.ToAnyWithValidation(response); err != nil {
+ return nil, err
+ }
+
+ return &matcherv3.Matcher_OnMatch_Action{
+ Action: &cncfv3.TypedExtensionConfig{
+ Name: r.Name,
+ TypedConfig: pb,
+ },
+ }, nil
+}
+
+// routeContainsResponseOverride returns true if ResponseOverride exists for the provided route.
+func (c *customResponse) routeContainsResponseOverride(irRoute *ir.HTTPRoute) bool {
+ if irRoute != nil &&
+ irRoute.Traffic != nil &&
+ irRoute.Traffic.ResponseOverride != nil {
+ return true
+ }
+ return false
+}
+
+func (c *customResponse) patchResources(tCtx *types.ResourceVersionTable,
+ routes []*ir.HTTPRoute,
+) error {
+ return nil
+}
+
+// patchRoute patches the provided route with the customResponse config if applicable.
+// Note: this method enables the corresponding customResponse filter for the provided route.
+func (c *customResponse) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
+ if route == nil {
+ return errors.New("xds route is nil")
+ }
+ if irRoute == nil {
+ return errors.New("ir route is nil")
+ }
+ if irRoute.Traffic == nil || irRoute.Traffic.ResponseOverride == nil {
+ return nil
+ }
+ filterName := c.customResponseFilterName(irRoute.Traffic.ResponseOverride)
+ if err := enableFilterOnRoute(route, filterName); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go
index 35ca41e79f6..f65cc0875f3 100644
--- a/internal/xds/translator/extauth.go
+++ b/internal/xds/translator/extauth.go
@@ -103,6 +103,10 @@ func extAuthConfig(extAuth *ir.ExtAuth) *extauthv3.ExtAuthz {
config.FailureModeAllow = *extAuth.FailOpen
}
+ if extAuth.RecomputeRoute != nil {
+ config.ClearRouteCache = *extAuth.RecomputeRoute
+ }
+
var headersToExtAuth []*matcherv3.StringMatcher
for _, header := range extAuth.HeadersToExtAuth {
headersToExtAuth = append(headersToExtAuth, &matcherv3.StringMatcher{
@@ -113,6 +117,12 @@ func extAuthConfig(extAuth *ir.ExtAuth) *extauthv3.ExtAuthz {
})
}
+ if extAuth.BodyToExtAuth != nil {
+ config.WithRequestBody = &extauthv3.BufferSettings{
+ MaxRequestBytes: extAuth.BodyToExtAuth.MaxRequestBytes,
+ }
+ }
+
if len(headersToExtAuth) > 0 {
config.AllowedHeaders = &matcherv3.ListStringMatcher{
Patterns: headersToExtAuth,
@@ -222,14 +232,12 @@ func (*extAuth) patchResources(tCtx *types.ResourceVersionTable,
}
if route.Security.ExtAuth.HTTP != nil {
if err := createExtServiceXDSCluster(
- &route.Security.ExtAuth.HTTP.Destination, tCtx); err != nil && !errors.Is(
- err, ErrXdsClusterExists) {
+ &route.Security.ExtAuth.HTTP.Destination, route.Security.ExtAuth.Traffic, tCtx); err != nil {
errs = errors.Join(errs, err)
}
} else {
if err := createExtServiceXDSCluster(
- &route.Security.ExtAuth.GRPC.Destination, tCtx); err != nil && !errors.Is(
- err, ErrXdsClusterExists) {
+ &route.Security.ExtAuth.GRPC.Destination, route.Security.ExtAuth.Traffic, tCtx); err != nil {
errs = errors.Join(errs, err)
}
}
diff --git a/internal/xds/translator/extproc.go b/internal/xds/translator/extproc.go
index 6f4db53a08b..2270b2fb79d 100644
--- a/internal/xds/translator/extproc.go
+++ b/internal/xds/translator/extproc.go
@@ -137,6 +137,18 @@ func extProcConfig(extProc ir.ExtProc) *extprocv3.ExternalProcessor {
config.ProcessingMode.ResponseHeaderMode = extprocv3.ProcessingMode_SEND
}
+ if extProc.RequestAttributes != nil {
+ var attrs []string
+ attrs = append(attrs, extProc.RequestAttributes...)
+ config.RequestAttributes = attrs
+ }
+
+ if extProc.ResponseAttributes != nil {
+ var attrs []string
+ attrs = append(attrs, extProc.ResponseAttributes...)
+ config.ResponseAttributes = attrs
+ }
+
return config
}
@@ -173,12 +185,10 @@ func (*extProc) patchResources(tCtx *types.ResourceVersionTable,
for i := range route.EnvoyExtensions.ExtProcs {
ep := route.EnvoyExtensions.ExtProcs[i]
if err := createExtServiceXDSCluster(
- &ep.Destination, tCtx); err != nil && !errors.Is(
- err, ErrXdsClusterExists) {
+ &ep.Destination, ep.Traffic, tCtx); err != nil {
errs = errors.Join(errs, err)
}
}
-
}
return errs
diff --git a/internal/xds/translator/fault.go b/internal/xds/translator/fault.go
index e0acbd6c840..192ce5bf8e9 100644
--- a/internal/xds/translator/fault.go
+++ b/internal/xds/translator/fault.go
@@ -20,6 +20,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils/protocov"
"github.com/envoyproxy/gateway/internal/xds/types"
)
@@ -71,7 +72,7 @@ func buildHCMFaultFilter() (*hcmv3.HttpFilter, error) {
return nil, err
}
- faultAny, err := anypb.New(faultProto)
+ faultAny, err := protocov.ToAnyWithValidation(faultProto)
if err != nil {
return nil, err
}
@@ -165,7 +166,7 @@ func (*fault) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
return nil
}
- routeCfgAny, err := anypb.New(routeCfgProto)
+ routeCfgAny, err := protocov.ToAnyWithValidation(routeCfgProto)
if err != nil {
return err
}
diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go
index ad5789fb6ff..1b994fba669 100644
--- a/internal/xds/translator/httpfilters.go
+++ b/internal/xds/translator/httpfilters.go
@@ -114,8 +114,10 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter {
order = 5
case isFilterType(filter, egv1a1.EnvoyFilterJWTAuthn):
order = 6
+ case isFilterType(filter, egv1a1.EnvoyFilterSessionPersistence):
+ order = 7
case isFilterType(filter, egv1a1.EnvoyFilterExtProc):
- order = 7 + mustGetFilterIndex(filter.Name)
+ order = 8 + mustGetFilterIndex(filter.Name)
case isFilterType(filter, egv1a1.EnvoyFilterWasm):
order = 100 + mustGetFilterIndex(filter.Name)
case isFilterType(filter, egv1a1.EnvoyFilterRBAC):
diff --git a/internal/xds/translator/jsonpatch.go b/internal/xds/translator/jsonpatch.go
index e7808abe0c5..8a56ed689e4 100644
--- a/internal/xds/translator/jsonpatch.go
+++ b/internal/xds/translator/jsonpatch.go
@@ -16,23 +16,18 @@ import (
routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
tlsv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3"
- jsonpatchv5 "github.com/evanphx/json-patch/v5"
"google.golang.org/protobuf/encoding/protojson"
"sigs.k8s.io/yaml"
"github.com/envoyproxy/gateway/internal/gatewayapi/status"
"github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils/jsonpatch"
_ "github.com/envoyproxy/gateway/internal/xds/extensions" // register the generated types to support protojson unmarshalling
"github.com/envoyproxy/gateway/internal/xds/types"
)
const (
- AddOperation = "add"
- RemoveOperation = "remove"
- ReplaceOperation = "replace"
- CopyOperation = "copy"
- MoveOperation = "move"
- EmptyPath = ""
+ EmptyPath = ""
)
type typedName struct {
@@ -69,24 +64,14 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
err error
)
- switch p.Operation.Op {
- case AddOperation, ReplaceOperation:
- if p.Operation.Value == nil {
- tErr := fmt.Errorf("the %s operation requires a value", p.Operation.Op)
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- default:
- if p.Operation.Value != nil {
- tErr := fmt.Errorf("the value field can not be set for the %s operation", p.Operation.Op)
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
+ if err := p.Operation.Validate(); err != nil {
+ tErrs = errors.Join(tErrs, err)
+ continue
}
- // If Path is "" and op is "add", unmarshal and add the patch as a complete
+ // If Path and JSONPath is "" and op is "add", unmarshal and add the patch as a complete
// resource
- if p.Operation.Op == AddOperation && p.Operation.Path == EmptyPath {
+ if p.Operation.Op == ir.JSONPatchOpAdd && p.Operation.IsPathNilOrEmpty() && p.Operation.IsJSONPathNilOrEmpty() {
// Convert patch to JSON
// The patch library expects an array so convert it into one
y, err := yaml.Marshal(p.Operation.Value)
@@ -106,7 +91,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.ListenerType:
temp := &listenerv3.Listener{}
if err = protojson.Unmarshal(jsonBytes, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, p.Operation.Value))
+ tErr := errors.New(unmarshalErrorMessage(err, p.Operation.Value))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -119,7 +104,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.RouteType:
temp := &routev3.RouteConfiguration{}
if err = protojson.Unmarshal(jsonBytes, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, p.Operation.Value))
+ tErr := errors.New(unmarshalErrorMessage(err, p.Operation.Value))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -132,7 +117,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.ClusterType:
temp := &clusterv3.Cluster{}
if err = protojson.Unmarshal(jsonBytes, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, p.Operation.Value))
+ tErr := errors.New(unmarshalErrorMessage(err, p.Operation.Value))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -145,7 +130,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.EndpointType:
temp := &endpointv3.ClusterLoadAssignment{}
if err = protojson.Unmarshal(jsonBytes, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, p.Operation.Value))
+ tErr := errors.New(unmarshalErrorMessage(err, p.Operation.Value))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -158,7 +143,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.SecretType:
temp := &tlsv3.Secret{}
if err = protojson.Unmarshal(jsonBytes, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, p.Operation.Value))
+ tErr := errors.New(unmarshalErrorMessage(err, p.Operation.Value))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -240,34 +225,9 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
}
}
- // Convert patch to JSON
- // The patch library expects an array so convert it into one
- y, err := yaml.Marshal([]ir.JSONPatchOperation{p.Operation})
- if err != nil {
- tErr := fmt.Errorf("unable to marshal patch %+v, err: %s", p.Operation, err.Error())
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- jsonBytes, err := yaml.YAMLToJSON(y)
- if err != nil {
- tErr := fmt.Errorf("unable to convert patch to json %s, err: %s", string(y), err.Error())
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- patchObj, err := jsonpatchv5.DecodePatch(jsonBytes)
- if err != nil {
- tErr := fmt.Errorf("unable to decode patch %s, err: %s", string(jsonBytes), err.Error())
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
-
- // Apply patch
- opts := jsonpatchv5.NewApplyOptions()
- opts.EnsurePathExistsOnAdd = true
- modifiedJSON, err := patchObj.ApplyWithOptions(resourceJSON, opts)
+ modifiedJSON, err := jsonpatch.ApplyJSONPatches(resourceJSON, p.Operation)
if err != nil {
- tErr := fmt.Errorf("unable to apply patch:\n%s on resource:\n%s, err: %s", string(jsonBytes), string(resourceJSON), err.Error())
- tErrs = errors.Join(tErrs, tErr)
+ tErrs = errors.Join(tErrs, err)
continue
}
@@ -278,7 +238,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.ListenerType:
temp := &listenerv3.Listener{}
if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, string(modifiedJSON)))
+ tErr := errors.New(unmarshalErrorMessage(err, string(modifiedJSON)))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -295,7 +255,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.RouteType:
temp := &routev3.RouteConfiguration{}
if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, string(modifiedJSON)))
+ tErr := errors.New(unmarshalErrorMessage(err, string(modifiedJSON)))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -312,7 +272,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.ClusterType:
temp := &clusterv3.Cluster{}
if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, string(modifiedJSON)))
+ tErr := errors.New(unmarshalErrorMessage(err, string(modifiedJSON)))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -329,7 +289,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.EndpointType:
temp := &endpointv3.ClusterLoadAssignment{}
if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, string(modifiedJSON)))
+ tErr := errors.New(unmarshalErrorMessage(err, string(modifiedJSON)))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -346,7 +306,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.SecretType:
temp := &tlsv3.Secret{}
if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, string(modifiedJSON)))
+ tErr := errors.New(unmarshalErrorMessage(err, string(modifiedJSON)))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -361,6 +321,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
continue
}
}
+
}
// Set translation errors for every policy ancestor references
diff --git a/internal/xds/translator/jwt.go b/internal/xds/translator/jwt.go
index 4d3a8583756..bc3e8d1b16e 100644
--- a/internal/xds/translator/jwt.go
+++ b/internal/xds/translator/jwt.go
@@ -22,6 +22,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils/protocov"
"github.com/envoyproxy/gateway/internal/xds/types"
)
@@ -76,11 +77,7 @@ func buildHCMJWTFilter(irListener *ir.HTTPListener) (*hcmv3.HttpFilter, error) {
return nil, err
}
- if err := jwtAuthnProto.ValidateAll(); err != nil {
- return nil, err
- }
-
- jwtAuthnAny, err := anypb.New(jwtAuthnProto)
+ jwtAuthnAny, err := protocov.ToAnyWithValidation(jwtAuthnProto)
if err != nil {
return nil, err
}
@@ -123,7 +120,6 @@ func buildJWTAuthn(irListener *ir.HTTPListener) (*jwtauthnv3.JwtAuthentication,
},
CacheDuration: &durationpb.Duration{Seconds: 5 * 60},
AsyncFetch: &jwtauthnv3.JwksAsyncFetch{},
- RetryPolicy: &corev3.RetryPolicy{},
},
}
@@ -139,9 +135,13 @@ func buildJWTAuthn(irListener *ir.HTTPListener) (*jwtauthnv3.JwtAuthentication,
Issuer: irProvider.Issuer,
Audiences: irProvider.Audiences,
JwksSourceSpecifier: remote,
- PayloadInMetadata: irProvider.Issuer,
+ PayloadInMetadata: irProvider.Name,
ClaimToHeaders: claimToHeaders,
Forward: true,
+ NormalizePayloadInMetadata: &jwtauthnv3.JwtProvider_NormalizePayload{
+ // Normalize the scopes to facilitate matching in Authorization.
+ SpaceDelimitedClaims: []string{"scope"},
+ },
}
if irProvider.RecomputeRoute != nil {
@@ -210,7 +210,7 @@ func buildXdsUpstreamTLSSocket(sni string) (*corev3.TransportSocket, error) {
},
}
- tlsCtxAny, err := anypb.New(tlsCtxProto)
+ tlsCtxAny, err := protocov.ToAnyWithValidation(tlsCtxProto)
if err != nil {
return nil, err
}
@@ -243,7 +243,7 @@ func (*jwt) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
RequirementSpecifier: &jwtauthnv3.PerRouteConfig_RequirementName{RequirementName: irRoute.Name},
}
- routeCfgAny, err := anypb.New(routeCfgProto)
+ routeCfgAny, err := protocov.ToAnyWithValidation(routeCfgProto)
if err != nil {
return err
}
diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go
index ee1f5c7d133..36cf9a8953b 100644
--- a/internal/xds/translator/listener.go
+++ b/internal/xds/translator/listener.go
@@ -7,9 +7,12 @@ package translator
import (
"errors"
+ "strconv"
+ "strings"
xdscore "github.com/cncf/xds/go/xds/core/v3"
matcher "github.com/cncf/xds/go/xds/type/matcher/v3"
+ mutation_rulesv3 "github.com/envoyproxy/go-control-plane/envoy/config/common/mutation_rules/v3"
corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
tls_inspectorv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/tls_inspector/v3"
@@ -17,6 +20,7 @@ import (
hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
tcpv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3"
udpv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/udp/udp_proxy/v3"
+ early_header_mutationv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/early_header_mutation/header_mutation/v3"
preservecasev3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/header_formatters/preserve_case/v3"
customheaderv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/original_ip_detection/custom_header/v3"
quicv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/quic/v3"
@@ -25,7 +29,6 @@ import (
"github.com/envoyproxy/go-control-plane/pkg/resource/v3"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
"google.golang.org/protobuf/proto"
- "google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/wrapperspb"
"k8s.io/utils/ptr"
@@ -62,7 +65,7 @@ func http1ProtocolOptions(opts *ir.HTTP1Settings) *corev3.Http1ProtocolOptions {
EnableTrailers: opts.EnableTrailers,
}
if opts.PreserveHeaderCase {
- preservecaseAny, _ := anypb.New(&preservecasev3.PreserveCaseFormatterConfig{})
+ preservecaseAny, _ := protocov.ToAnyWithValidation(&preservecasev3.PreserveCaseFormatterConfig{})
r.HeaderKeyFormat = &corev3.Http1ProtocolOptions_HeaderKeyFormat{
HeaderFormat: &corev3.Http1ProtocolOptions_HeaderKeyFormat_StatefulFormatter{
StatefulFormatter: &corev3.TypedExtensionConfig{
@@ -84,7 +87,7 @@ func http2ProtocolOptions(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions {
opts = &ir.HTTP2Settings{}
}
- return &corev3.Http2ProtocolOptions{
+ out := &corev3.Http2ProtocolOptions{
MaxConcurrentStreams: &wrapperspb.UInt32Value{
Value: ptr.Deref(opts.MaxConcurrentStreams, http2MaxConcurrentStreamsLimit),
},
@@ -95,6 +98,14 @@ func http2ProtocolOptions(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions {
Value: ptr.Deref(opts.InitialConnectionWindowSize, http2InitialConnectionWindowSize),
},
}
+
+ if opts.ResetStreamOnError != nil {
+ out.OverrideStreamErrorOnInvalidHttpMessage = &wrapperspb.BoolValue{
+ Value: *opts.ResetStreamOnError,
+ }
+ }
+
+ return out
}
func xffNumTrustedHops(clientIPDetection *ir.ClientIPDetectionSettings) uint32 {
@@ -119,7 +130,7 @@ func originalIPDetectionExtensions(clientIPDetection *ir.ClientIPDetectionSettin
rejectWithStatus = &typev3.HttpStatus{Code: typev3.StatusCode_Forbidden}
}
- customHeaderConfigAny, _ := anypb.New(&customheaderv3.CustomHeaderConfig{
+ customHeaderConfigAny, _ := protocov.ToAnyWithValidation(&customheaderv3.CustomHeaderConfig{
HeaderName: clientIPDetection.CustomHeader.Name,
RejectWithStatus: rejectWithStatus,
@@ -137,11 +148,21 @@ func originalIPDetectionExtensions(clientIPDetection *ir.ClientIPDetectionSettin
// buildXdsTCPListener creates a xds Listener resource
// TODO: Improve function parameters
-func buildXdsTCPListener(name, address string, port uint32, keepalive *ir.TCPKeepalive, connection *ir.ClientConnection, accesslog *ir.AccessLog) *listenerv3.Listener {
+func buildXdsTCPListener(
+ name, address string,
+ port uint32,
+ ipFamily *ir.IPFamily,
+ keepalive *ir.TCPKeepalive,
+ connection *ir.ClientConnection,
+ accesslog *ir.AccessLog,
+) (*listenerv3.Listener, error) {
socketOptions := buildTCPSocketOptions(keepalive)
- al := buildXdsAccessLog(accesslog, true)
+ al, err := buildXdsAccessLog(accesslog, ir.ProxyAccessLogTypeListener)
+ if err != nil {
+ return nil, err
+ }
bufferLimitBytes := buildPerConnectionBufferLimitBytes(connection)
- return &listenerv3.Listener{
+ listener := &listenerv3.Listener{
Name: name,
AccessLog: al,
SocketOptions: socketOptions,
@@ -157,10 +178,14 @@ func buildXdsTCPListener(name, address string, port uint32, keepalive *ir.TCPKee
},
},
},
- // Remove /healthcheck/fail from endpoints that trigger a drain of listeners for better control
- // over the drain process while still allowing the healthcheck to be failed during pod shutdown.
- DrainType: listenerv3.Listener_MODIFY_ONLY,
}
+
+ if ipFamily != nil && *ipFamily == egv1a1.DualStack {
+ socketAddress := listener.Address.GetSocketAddress()
+ socketAddress.Ipv4Compat = true
+ }
+
+ return listener, nil
}
func buildPerConnectionBufferLimitBytes(connection *ir.ClientConnection) *wrapperspb.UInt32Value {
@@ -171,10 +196,14 @@ func buildPerConnectionBufferLimitBytes(connection *ir.ClientConnection) *wrappe
}
// buildXdsQuicListener creates a xds Listener resource for quic
-func buildXdsQuicListener(name, address string, port uint32, accesslog *ir.AccessLog) *listenerv3.Listener {
+func buildXdsQuicListener(name, address string, port uint32, ipFamily *ir.IPFamily, accesslog *ir.AccessLog) (*listenerv3.Listener, error) {
+ log, err := buildXdsAccessLog(accesslog, ir.ProxyAccessLogTypeListener)
+ if err != nil {
+ return nil, err
+ }
xdsListener := &listenerv3.Listener{
Name: name + "-quic",
- AccessLog: buildXdsAccessLog(accesslog, true),
+ AccessLog: log,
Address: &corev3.Address{
Address: &corev3.Address_SocketAddress{
SocketAddress: &corev3.SocketAddress{
@@ -195,7 +224,12 @@ func buildXdsQuicListener(name, address string, port uint32, accesslog *ir.Acces
DrainType: listenerv3.Listener_MODIFY_ONLY,
}
- return xdsListener
+ if ipFamily != nil && *ipFamily == egv1a1.DualStack {
+ socketAddress := xdsListener.Address.GetSocketAddress()
+ socketAddress.Ipv4Compat = true
+ }
+
+ return xdsListener, nil
}
// addHCMToXDSListener adds a HCM filter to the listener's filter chain, and adds
@@ -211,7 +245,10 @@ func buildXdsQuicListener(name, address string, port uint32, accesslog *ir.Acces
func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irListener *ir.HTTPListener,
accesslog *ir.AccessLog, tracing *ir.Tracing, http3Listener bool, connection *ir.ClientConnection,
) error {
- al := buildXdsAccessLog(accesslog, false)
+ al, err := buildXdsAccessLog(accesslog, ir.ProxyAccessLogTypeRoute)
+ if err != nil {
+ return err
+ }
hcmTracing, err := buildHCMTracing(tracing)
if err != nil {
@@ -226,6 +263,9 @@ func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irLis
statPrefix = "http"
}
+ // Append port to the statPrefix.
+ statPrefix = strings.Join([]string{statPrefix, strconv.Itoa(int(irListener.Port))}, "-")
+
// Client IP detection
useRemoteAddress := true
originalIPDetectionExtensions := originalIPDetectionExtensions(irListener.ClientIPDetection)
@@ -261,9 +301,10 @@ func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irLis
CommonHttpProtocolOptions: &corev3.HttpProtocolOptions{
HeadersWithUnderscoresAction: buildHeadersWithUnderscoresAction(irListener.Headers),
},
- Tracing: hcmTracing,
- ForwardClientCertDetails: buildForwardClientCertDetailsAction(irListener.Headers),
- PreserveExternalRequestId: ptr.Deref(irListener.Headers, ir.HeaderSettings{}).PreserveXRequestID,
+ Tracing: hcmTracing,
+ ForwardClientCertDetails: buildForwardClientCertDetailsAction(irListener.Headers),
+ PreserveExternalRequestId: ptr.Deref(irListener.Headers, ir.HeaderSettings{}).PreserveXRequestID,
+ EarlyHeaderMutationExtensions: buildEarlyHeaderMutation(irListener.Headers),
}
if mgr.ForwardClientCertDetails == hcmv3.HttpConnectionManager_APPEND_FORWARD || mgr.ForwardClientCertDetails == hcmv3.HttpConnectionManager_SANITIZE_SET {
@@ -352,6 +393,73 @@ func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irLis
return nil
}
+func buildEarlyHeaderMutation(headers *ir.HeaderSettings) []*corev3.TypedExtensionConfig {
+ if headers == nil || (len(headers.EarlyAddRequestHeaders) == 0 && len(headers.EarlyRemoveRequestHeaders) == 0) {
+ return nil
+ }
+
+ var mutationRules []*mutation_rulesv3.HeaderMutation
+
+ for _, header := range headers.EarlyAddRequestHeaders {
+ var appendAction corev3.HeaderValueOption_HeaderAppendAction
+ if header.Append {
+ appendAction = corev3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD
+ } else {
+ appendAction = corev3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD
+ }
+ // Allow empty headers to be set, but don't add the config to do so unless necessary
+ if len(header.Value) == 0 {
+ mutationRules = append(mutationRules, &mutation_rulesv3.HeaderMutation{
+ Action: &mutation_rulesv3.HeaderMutation_Append{
+ Append: &corev3.HeaderValueOption{
+ Header: &corev3.HeaderValue{
+ Key: header.Name,
+ },
+ AppendAction: appendAction,
+ KeepEmptyValue: true,
+ },
+ },
+ })
+ } else {
+ for _, val := range header.Value {
+ mutationRules = append(mutationRules, &mutation_rulesv3.HeaderMutation{
+ Action: &mutation_rulesv3.HeaderMutation_Append{
+ Append: &corev3.HeaderValueOption{
+ Header: &corev3.HeaderValue{
+ Key: header.Name,
+ Value: val,
+ },
+ AppendAction: appendAction,
+ KeepEmptyValue: val == "",
+ },
+ },
+ })
+ }
+ }
+ }
+
+ for _, header := range headers.EarlyRemoveRequestHeaders {
+ mr := &mutation_rulesv3.HeaderMutation{
+ Action: &mutation_rulesv3.HeaderMutation_Remove{
+ Remove: header,
+ },
+ }
+
+ mutationRules = append(mutationRules, mr)
+ }
+
+ earlyHeaderMutationAny, _ := protocov.ToAnyWithValidation(&early_header_mutationv3.HeaderMutation{
+ Mutations: mutationRules,
+ })
+
+ return []*corev3.TypedExtensionConfig{
+ {
+ Name: "envoy.http.early_header_mutation.header_mutation",
+ TypedConfig: earlyHeaderMutationAny,
+ },
+ }
+}
+
func addServerNamesMatch(xdsListener *listenerv3.Listener, filterChain *listenerv3.FilterChain, hostnames []string) error {
// Dont add a filter chain match if the hostname is a wildcard character.
if len(hostnames) > 0 && hostnames[0] != "*" {
@@ -403,15 +511,21 @@ func addXdsTCPFilterChain(xdsListener *listenerv3.Listener, irRoute *ir.TCPRoute
isTLSTerminate := irRoute.TLS != nil && irRoute.TLS.Terminate != nil
statPrefix := "tcp"
if isTLSPassthrough {
- statPrefix = "passthrough"
+ statPrefix = "tls-passthrough"
}
if isTLSTerminate {
- statPrefix = "terminate"
+ statPrefix = "tls-terminate"
}
+ // Append port to the statPrefix.
+ statPrefix = strings.Join([]string{statPrefix, strconv.Itoa(int(xdsListener.Address.GetSocketAddress().GetPortValue()))}, "-")
+ al, error := buildXdsAccessLog(accesslog, ir.ProxyAccessLogTypeRoute)
+ if error != nil {
+ return error
+ }
mgr := &tcpv3.TcpProxy{
- AccessLog: buildXdsAccessLog(accesslog, false),
+ AccessLog: al,
StatPrefix: statPrefix,
ClusterSpecifier: &tcpv3.TcpProxy_Cluster{
Cluster: clusterName,
@@ -495,7 +609,7 @@ func addXdsTLSInspectorFilter(xdsListener *listenerv3.Listener) error {
}
tlsInspector := &tls_inspectorv3.TlsInspector{}
- tlsInspectorAny, err := anypb.New(tlsInspector)
+ tlsInspectorAny, err := protocov.ToAnyWithValidation(tlsInspector)
if err != nil {
return err
}
@@ -541,7 +655,9 @@ func buildDownstreamQUICTransportSocket(tlsConfig *ir.TLSConfig) (*corev3.Transp
}
}
- tlsCtxAny, err := anypb.New(tlsCtx)
+ setDownstreamTLSSessionSettings(tlsConfig, tlsCtx.DownstreamTlsContext)
+
+ tlsCtxAny, err := protocov.ToAnyWithValidation(tlsCtx)
if err != nil {
return nil, err
}
@@ -581,7 +697,9 @@ func buildXdsDownstreamTLSSocket(tlsConfig *ir.TLSConfig) (*corev3.TransportSock
}
}
- tlsCtxAny, err := anypb.New(tlsCtx)
+ setDownstreamTLSSessionSettings(tlsConfig, tlsCtx)
+
+ tlsCtxAny, err := protocov.ToAnyWithValidation(tlsCtx)
if err != nil {
return nil, err
}
@@ -594,6 +712,18 @@ func buildXdsDownstreamTLSSocket(tlsConfig *ir.TLSConfig) (*corev3.TransportSock
}, nil
}
+func setDownstreamTLSSessionSettings(tlsConfig *ir.TLSConfig, tlsCtx *tlsv3.DownstreamTlsContext) {
+ if !tlsConfig.StatefulSessionResumption {
+ tlsCtx.DisableStatefulSessionResumption = true
+ }
+
+ if !tlsConfig.StatelessSessionResumption {
+ tlsCtx.SessionTicketKeysType = &tlsv3.DownstreamTlsContext_DisableStatelessSessionResumption{
+ DisableStatelessSessionResumption: true,
+ }
+ }
+}
+
func buildTLSParams(tlsConfig *ir.TLSConfig) *tlsv3.TlsParameters {
p := &tlsv3.TlsParameters{}
isEmpty := true
@@ -637,11 +767,12 @@ func buildTLSVersion(version *ir.TLSVersion) tlsv3.TlsParameters_TlsProtocol {
}
func buildALPNProtocols(alpn []string) []string {
- if len(alpn) == 0 {
+ if alpn == nil { // not set - default to h2 and http/1.1
out := []string{"h2", "http/1.1"}
return out
+ } else {
+ return alpn
}
- return alpn
}
func buildXdsTLSCertSecret(tlsConfig ir.TLSCertificate) *tlsv3.Secret {
@@ -683,14 +814,18 @@ func buildXdsUDPListener(clusterName string, udpListener *ir.UDPListener, access
route := &udpv3.Route{
Cluster: clusterName,
}
- routeAny, err := anypb.New(route)
+ routeAny, err := protocov.ToAnyWithValidation(route)
if err != nil {
return nil, err
}
+ al, error := buildXdsAccessLog(accesslog, ir.ProxyAccessLogTypeRoute)
+ if error != nil {
+ return nil, error
+ }
udpProxy := &udpv3.UdpProxyConfig{
StatPrefix: statPrefix,
- AccessLog: buildXdsAccessLog(accesslog, false),
+ AccessLog: al,
RouteSpecifier: &udpv3.UdpProxyConfig_Matcher{
Matcher: &matcher.Matcher{
OnNoMatch: &matcher.Matcher_OnMatch{
@@ -704,14 +839,17 @@ func buildXdsUDPListener(clusterName string, udpListener *ir.UDPListener, access
},
},
}
- udpProxyAny, err := anypb.New(udpProxy)
+ udpProxyAny, err := protocov.ToAnyWithValidation(udpProxy)
if err != nil {
return nil, err
}
+ if al, err = buildXdsAccessLog(accesslog, ir.ProxyAccessLogTypeListener); err != nil {
+ return nil, err
+ }
xdsListener := &listenerv3.Listener{
Name: udpListener.Name,
- AccessLog: buildXdsAccessLog(accesslog, true),
+ AccessLog: al,
Address: &corev3.Address{
Address: &corev3.Address_SocketAddress{
SocketAddress: &corev3.SocketAddress{
@@ -731,6 +869,11 @@ func buildXdsUDPListener(clusterName string, udpListener *ir.UDPListener, access
}},
}
+ if udpListener.IPFamily != nil && *udpListener.IPFamily == egv1a1.DualStack {
+ socketAddress := xdsListener.Address.GetSocketAddress()
+ socketAddress.Ipv4Compat = true
+ }
+
return xdsListener, nil
}
@@ -758,7 +901,7 @@ func translateEscapePath(in ir.PathEscapedSlashAction) hcmv3.HttpConnectionManag
}
func toNetworkFilter(filterName string, filterProto proto.Message) (*listenerv3.Filter, error) {
- filterAny, err := protocov.ToAnyWithError(filterProto)
+ filterAny, err := protocov.ToAnyWithValidation(filterProto)
if err != nil {
return nil, err
}
diff --git a/internal/xds/translator/listener_test.go b/internal/xds/translator/listener_test.go
index 28572bb06be..fbb716c1ac4 100644
--- a/internal/xds/translator/listener_test.go
+++ b/internal/xds/translator/listener_test.go
@@ -10,6 +10,7 @@ import (
"reflect"
"testing"
+ routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
typev3 "github.com/envoyproxy/go-control-plane/envoy/type/v3"
"github.com/stretchr/testify/assert"
@@ -25,12 +26,24 @@ func Test_toNetworkFilter(t *testing.T) {
wantErr error
}{
{
- name: "valid filter",
- proto: &hcmv3.HttpConnectionManager{},
+ name: "valid filter",
+ proto: &hcmv3.HttpConnectionManager{
+ StatPrefix: "stats",
+ RouteSpecifier: &hcmv3.HttpConnectionManager_RouteConfig{
+ RouteConfig: &routev3.RouteConfiguration{
+ Name: "route",
+ },
+ },
+ },
wantErr: nil,
},
{
name: "invalid proto msg",
+ proto: &hcmv3.HttpConnectionManager{},
+ wantErr: errors.New("invalid HttpConnectionManager.StatPrefix: value length must be at least 1 runes; invalid HttpConnectionManager.RouteSpecifier: value is required"),
+ },
+ {
+ name: "nil proto msg",
proto: nil,
wantErr: errors.New("empty message received"),
},
@@ -39,7 +52,7 @@ func Test_toNetworkFilter(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
_, err := toNetworkFilter("name", tt.proto)
if tt.wantErr != nil {
- assert.Equalf(t, tt.wantErr, err, "toNetworkFilter(%v)", tt.proto)
+ assert.Containsf(t, err.Error(), tt.wantErr.Error(), "toNetworkFilter(%v)", tt.proto)
} else {
assert.NoErrorf(t, err, "toNetworkFilter(%v)", tt.proto)
}
diff --git a/internal/xds/translator/local_ratelimit.go b/internal/xds/translator/local_ratelimit.go
index 1503758dfb4..ea3c4351629 100644
--- a/internal/xds/translator/local_ratelimit.go
+++ b/internal/xds/translator/local_ratelimit.go
@@ -16,11 +16,11 @@ import (
hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
typev3 "github.com/envoyproxy/go-control-plane/envoy/type/v3"
"google.golang.org/protobuf/types/known/anypb"
- "google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/wrapperspb"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils/ratelimit"
"github.com/envoyproxy/gateway/internal/xds/types"
)
@@ -151,7 +151,7 @@ func (*localRateLimit) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) e
TokensPerFill: &wrapperspb.UInt32Value{
Value: uint32(local.Default.Requests),
},
- FillInterval: ratelimitUnitToDuration(local.Default.Unit),
+ FillInterval: ratelimit.UnitToDuration(local.Default.Unit),
},
FilterEnabled: &configv3.RuntimeFractionalPercent{
DefaultValue: &typev3.FractionalPercent{
@@ -218,13 +218,17 @@ func buildRouteLocalRateLimits(local *ir.LocalRateLimit) (
StringMatch: buildXdsStringMatcher(match),
},
}
+ expectMatch := true
+ if match.Invert != nil && *match.Invert {
+ expectMatch = false
+ }
action := &routev3.RateLimit_Action{
ActionSpecifier: &routev3.RateLimit_Action_HeaderValueMatch_{
HeaderValueMatch: &routev3.RateLimit_Action_HeaderValueMatch{
DescriptorKey: descriptorKey,
DescriptorValue: descriptorVal,
ExpectMatch: &wrapperspb.BoolValue{
- Value: true,
+ Value: expectMatch,
},
Headers: []*routev3.HeaderMatcher{headerMatcher},
},
@@ -277,7 +281,7 @@ func buildRouteLocalRateLimits(local *ir.LocalRateLimit) (
TokensPerFill: &wrapperspb.UInt32Value{
Value: uint32(rule.Limit.Requests),
},
- FillInterval: ratelimitUnitToDuration(rule.Limit.Unit),
+ FillInterval: ratelimit.UnitToDuration(rule.Limit.Unit),
},
}
descriptors = append(descriptors, descriptor)
@@ -285,21 +289,3 @@ func buildRouteLocalRateLimits(local *ir.LocalRateLimit) (
return rateLimits, descriptors, nil
}
-
-func ratelimitUnitToDuration(unit ir.RateLimitUnit) *durationpb.Duration {
- var seconds int64
-
- switch egv1a1.RateLimitUnit(unit) {
- case egv1a1.RateLimitUnitSecond:
- seconds = 1
- case egv1a1.RateLimitUnitMinute:
- seconds = 60
- case egv1a1.RateLimitUnitHour:
- seconds = 60 * 60
- case egv1a1.RateLimitUnitDay:
- seconds = 60 * 60 * 24
- }
- return &durationpb.Duration{
- Seconds: seconds,
- }
-}
diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go
index e04b601a24a..c51bbd75499 100644
--- a/internal/xds/translator/oidc.go
+++ b/internal/xds/translator/oidc.go
@@ -16,12 +16,12 @@ import (
tlsv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
matcherv3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
"github.com/golang/protobuf/ptypes/wrappers"
- "google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/durationpb"
"k8s.io/utils/ptr"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/utils/protocov"
"github.com/envoyproxy/gateway/internal/xds/types"
)
@@ -53,9 +53,9 @@ func (*oidc) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListe
continue
}
- // Only generates one BasicAuth Envoy filter for each unique name.
+ // Only generates one OAuth2 Envoy filter for each unique name.
// For example, if there are two routes under the same gateway with the
- // same BasicAuth config, only one BasicAuth filter will be generated.
+ // same OAuth2 config, only one OAuth2 filter will be generated.
if hcmContainsFilter(mgr, oauth2FilterName(route.Security.OIDC)) {
continue
}
@@ -83,7 +83,7 @@ func buildHCMOAuth2Filter(oidc *ir.OIDC) (*hcmv3.HttpFilter, error) {
return nil, err
}
- OAuth2Any, err := anypb.New(oauth2Proto)
+ OAuth2Any, err := protocov.ToAnyWithValidation(oauth2Proto)
if err != nil {
return nil, err
}
@@ -102,14 +102,24 @@ func oauth2FilterName(oidc *ir.OIDC) string {
}
func oauth2Config(oidc *ir.OIDC) (*oauth2v3.OAuth2, error) {
- cluster, err := url2Cluster(oidc.Provider.TokenEndpoint)
- if err != nil {
- return nil, err
- }
- if cluster.endpointType == EndpointTypeStatic {
- return nil, fmt.Errorf(
- "static IP cluster is not allowed: %s",
- oidc.Provider.TokenEndpoint)
+ var (
+ tokenEndpointCluster string
+ err error
+ )
+
+ if oidc.Provider.Destination != nil && len(oidc.Provider.Destination.Settings) > 0 {
+ tokenEndpointCluster = oidc.Provider.Destination.Name
+ } else {
+ var cluster *urlCluster
+ if cluster, err = url2Cluster(oidc.Provider.TokenEndpoint); err != nil {
+ return nil, err
+ }
+ if cluster.endpointType == EndpointTypeStatic {
+ return nil, fmt.Errorf(
+ "static IP cluster is not allowed: %s",
+ oidc.Provider.TokenEndpoint)
+ }
+ tokenEndpointCluster = cluster.name
}
// Envoy OAuth2 filter deletes the HTTP authorization header by default, which surprises users.
@@ -126,7 +136,7 @@ func oauth2Config(oidc *ir.OIDC) (*oauth2v3.OAuth2, error) {
TokenEndpoint: &corev3.HttpUri{
Uri: oidc.Provider.TokenEndpoint,
HttpUpstreamType: &corev3.HttpUri_Cluster{
- Cluster: cluster.name,
+ Cluster: tokenEndpointCluster,
},
Timeout: &durationpb.Duration{
Seconds: defaultExtServiceRequestTimeout,
@@ -172,6 +182,7 @@ func oauth2Config(oidc *ir.OIDC) (*oauth2v3.OAuth2, error) {
OauthExpires: fmt.Sprintf("OauthExpires-%s", oidc.CookieSuffix),
IdToken: fmt.Sprintf("IdToken-%s", oidc.CookieSuffix),
RefreshToken: fmt.Sprintf("RefreshToken-%s", oidc.CookieSuffix),
+ OauthNonce: fmt.Sprintf("OauthNonce-%s", oidc.CookieSuffix),
},
},
// every OIDC provider supports basic auth
@@ -205,9 +216,59 @@ func oauth2Config(oidc *ir.OIDC) (*oauth2v3.OAuth2, error) {
oauth2.Config.Credentials.CookieNames.IdToken = *oidc.CookieNameOverrides.IDToken
}
+ if oidc.CookieDomain != nil {
+ oauth2.Config.Credentials.CookieDomain = *oidc.CookieDomain
+ }
+
+ // Set the retry policy if it exists.
+ if oidc.Provider.Traffic != nil && oidc.Provider.Traffic.Retry != nil {
+ var rp *corev3.RetryPolicy
+ if rp, err = buildNonRouteRetryPolicy(oidc.Provider.Traffic.Retry); err != nil {
+ return nil, err
+ }
+ oauth2.Config.RetryPolicy = rp
+ }
return oauth2, nil
}
+func buildNonRouteRetryPolicy(rr *ir.Retry) (*corev3.RetryPolicy, error) {
+ rp := &corev3.RetryPolicy{
+ RetryOn: retryDefaultRetryOn,
+ }
+
+ // These two fields in the RetryPolicy are just for route-level retries, they are not used for non-route retries.
+ // retry.PerRetry.Timeout
+ // retry.RetryOn.HTTPStatusCodes
+
+ if rr.PerRetry != nil && rr.PerRetry.BackOff != nil {
+ rp.RetryBackOff = &corev3.BackoffStrategy{
+ BaseInterval: &durationpb.Duration{
+ Seconds: int64(rr.PerRetry.BackOff.BaseInterval.Seconds()),
+ },
+ MaxInterval: &durationpb.Duration{
+ Seconds: int64(rr.PerRetry.BackOff.MaxInterval.Seconds()),
+ },
+ }
+ }
+
+ if rr.NumRetries != nil {
+ rp.NumRetries = &wrappers.UInt32Value{
+ Value: *rr.NumRetries,
+ }
+ }
+
+ if rr.RetryOn != nil {
+ if len(rr.RetryOn.Triggers) > 0 {
+ if ro, err := buildRetryOn(rr.RetryOn.Triggers); err == nil {
+ rp.RetryOn = ro
+ } else {
+ return nil, err
+ }
+ }
+ }
+ return rp, nil
+}
+
// routeContainsOIDC returns true if OIDC exists for the provided route.
func routeContainsOIDC(irRoute *ir.HTTPRoute) bool {
if irRoute != nil &&
@@ -221,7 +282,7 @@ func routeContainsOIDC(irRoute *ir.HTTPRoute) bool {
func (*oidc) patchResources(tCtx *types.ResourceVersionTable,
routes []*ir.HTTPRoute,
) error {
- if err := createOAuth2TokenEndpointClusters(tCtx, routes); err != nil {
+ if err := createOAuthServerClusters(tCtx, routes); err != nil {
return err
}
if err := createOAuth2Secrets(tCtx, routes); err != nil {
@@ -230,9 +291,8 @@ func (*oidc) patchResources(tCtx *types.ResourceVersionTable,
return nil
}
-// createOAuth2TokenEndpointClusters creates token endpoint clusters from the
-// provided routes, if needed.
-func createOAuth2TokenEndpointClusters(tCtx *types.ResourceVersionTable,
+// createOAuthServerClusters creates clusters for the OAuth2 server.
+func createOAuthServerClusters(tCtx *types.ResourceVersionTable,
routes []*ir.HTTPRoute,
) error {
if tCtx == nil || tCtx.XdsResources == nil {
@@ -245,59 +305,73 @@ func createOAuth2TokenEndpointClusters(tCtx *types.ResourceVersionTable,
continue
}
- var (
- cluster *urlCluster
- ds *ir.DestinationSetting
- tSocket *corev3.TransportSocket
- err error
- )
+ oidc := route.Security.OIDC
- cluster, err = url2Cluster(route.Security.OIDC.Provider.TokenEndpoint)
- if err != nil {
- errs = errors.Join(errs, err)
- continue
+ // If the OIDC provider has a destination, use it.
+ if oidc.Provider.Destination != nil && len(oidc.Provider.Destination.Settings) > 0 {
+ if err := createExtServiceXDSCluster(
+ oidc.Provider.Destination, oidc.Provider.Traffic, tCtx); err != nil {
+ errs = errors.Join(errs, err)
+ }
+ } else {
+ // Create a cluster with the token endpoint url.
+ if err := createOAuth2TokenEndpointCluster(tCtx, oidc.Provider.TokenEndpoint); err != nil {
+ errs = errors.Join(errs, err)
+ }
}
+ }
- // EG does not support static IP clusters for token endpoint clusters.
- // This validation could be removed since it's already validated in the
- // Gateway API translator.
- if cluster.endpointType == EndpointTypeStatic {
- errs = errors.Join(errs, fmt.Errorf(
- "static IP cluster is not allowed: %s",
- route.Security.OIDC.Provider.TokenEndpoint))
- continue
- }
+ return errs
+}
- ds = &ir.DestinationSetting{
- Weight: ptr.To[uint32](1),
- Endpoints: []*ir.DestinationEndpoint{
- ir.NewDestEndpoint(
- cluster.hostname,
- cluster.port),
- },
- }
+// createOAuth2TokenEndpointClusters creates token endpoint clusters from the
+// provided routes, if needed.
+func createOAuth2TokenEndpointCluster(tCtx *types.ResourceVersionTable,
+ tokenEndpoint string,
+) error {
+ var (
+ cluster *urlCluster
+ ds *ir.DestinationSetting
+ tSocket *corev3.TransportSocket
+ err error
+ )
+
+ if cluster, err = url2Cluster(tokenEndpoint); err != nil {
+ return err
+ }
- clusterArgs := &xdsClusterArgs{
- name: cluster.name,
- settings: []*ir.DestinationSetting{ds},
- tSocket: tSocket,
- endpointType: cluster.endpointType,
- }
- if cluster.tls {
- tSocket, err = buildXdsUpstreamTLSSocket(cluster.hostname)
- if err != nil {
- errs = errors.Join(errs, err)
- continue
- }
- clusterArgs.tSocket = tSocket
- }
+ // EG does not support static IP clusters for token endpoint clusters.
+ // This validation could be removed since it's already validated in the
+ // Gateway API translator.
+ if cluster.endpointType == EndpointTypeStatic {
+ return fmt.Errorf(
+ "static IP cluster is not allowed: %s",
+ tokenEndpoint)
+ }
- if err = addXdsCluster(tCtx, clusterArgs); err != nil && !errors.Is(err, ErrXdsClusterExists) {
- errs = errors.Join(errs, err)
+ ds = &ir.DestinationSetting{
+ Weight: ptr.To[uint32](1),
+ Endpoints: []*ir.DestinationEndpoint{
+ ir.NewDestEndpoint(
+ cluster.hostname,
+ cluster.port),
+ },
+ }
+
+ clusterArgs := &xdsClusterArgs{
+ name: cluster.name,
+ settings: []*ir.DestinationSetting{ds},
+ tSocket: tSocket,
+ endpointType: cluster.endpointType,
+ }
+ if cluster.tls {
+ if tSocket, err = buildXdsUpstreamTLSSocket(cluster.hostname); err != nil {
+ return err
}
+ clusterArgs.tSocket = tSocket
}
- return errs
+ return addXdsCluster(tCtx, clusterArgs)
}
// createOAuth2Secrets creates OAuth2 client and HMAC secrets from the provided
diff --git a/internal/xds/translator/ratelimit.go b/internal/xds/translator/ratelimit.go
index 8e3e661f9d7..eb6a1c4a2cd 100644
--- a/internal/xds/translator/ratelimit.go
+++ b/internal/xds/translator/ratelimit.go
@@ -7,7 +7,6 @@ package translator
import (
"bytes"
- "errors"
"net/url"
"strconv"
"strings"
@@ -157,11 +156,12 @@ func buildRouteRateLimits(descriptorPrefix string, global *ir.GlobalRateLimit) [
// Matches are ANDed
rlActions := []*routev3.RateLimit_Action{routeDescriptor}
for mIdx, match := range rule.HeaderMatches {
+ var action *routev3.RateLimit_Action
// Case for distinct match
if match.Distinct {
// Setup RequestHeader actions
descriptorKey := getRouteRuleDescriptor(rIdx, mIdx)
- action := &routev3.RateLimit_Action{
+ action = &routev3.RateLimit_Action{
ActionSpecifier: &routev3.RateLimit_Action_RequestHeaders_{
RequestHeaders: &routev3.RateLimit_Action_RequestHeaders{
HeaderName: match.Name,
@@ -169,7 +169,6 @@ func buildRouteRateLimits(descriptorPrefix string, global *ir.GlobalRateLimit) [
},
},
}
- rlActions = append(rlActions, action)
} else {
// Setup HeaderValueMatch actions
descriptorKey := getRouteRuleDescriptor(rIdx, mIdx)
@@ -180,20 +179,24 @@ func buildRouteRateLimits(descriptorPrefix string, global *ir.GlobalRateLimit) [
StringMatch: buildXdsStringMatcher(match),
},
}
- action := &routev3.RateLimit_Action{
+ expectMatch := true
+ if match.Invert != nil && *match.Invert {
+ expectMatch = false
+ }
+ action = &routev3.RateLimit_Action{
ActionSpecifier: &routev3.RateLimit_Action_HeaderValueMatch_{
HeaderValueMatch: &routev3.RateLimit_Action_HeaderValueMatch{
DescriptorKey: descriptorKey,
DescriptorValue: descriptorVal,
ExpectMatch: &wrapperspb.BoolValue{
- Value: true,
+ Value: expectMatch,
},
Headers: []*routev3.HeaderMatcher{headerMatcher},
},
},
}
- rlActions = append(rlActions, action)
}
+ rlActions = append(rlActions, action)
}
// To be able to rate limit each individual IP, we need to use a nested descriptors structure in the configuration
@@ -232,7 +235,7 @@ func buildRouteRateLimits(descriptorPrefix string, global *ir.GlobalRateLimit) [
// Setup RemoteAddress action if distinct match is set
if rule.CIDRMatch.Distinct {
// Setup RemoteAddress action
- action := &routev3.RateLimit_Action{
+ action = &routev3.RateLimit_Action{
ActionSpecifier: &routev3.RateLimit_Action_RemoteAddress_{
RemoteAddress: &routev3.RateLimit_Action_RemoteAddress{},
},
@@ -241,8 +244,8 @@ func buildRouteRateLimits(descriptorPrefix string, global *ir.GlobalRateLimit) [
}
}
- // Case when header match is not set and the rate limit is applied
- // to all traffic.
+ // Case when both header and cidr match are not set and the ratelimit
+ // will be applied to all traffic.
if !rule.IsMatchSet() {
// Setup GenericKey action
action := &routev3.RateLimit_Action{
@@ -329,22 +332,21 @@ func BuildRateLimitServiceConfig(irListener *ir.HTTPListener) *rlsconfv3.RateLim
func buildRateLimitServiceDescriptors(global *ir.GlobalRateLimit) []*rlsconfv3.RateLimitDescriptor {
pbDescriptors := make([]*rlsconfv3.RateLimitDescriptor, 0, len(global.Rules))
+ // The order in which matching descriptors are built is consistent with
+ // the order in which ratelimit actions are built:
+ // 1) Header Matches
+ // 2) CIDR Match
+ // 3) No Match
for rIdx, rule := range global.Rules {
- var head, cur *rlsconfv3.RateLimitDescriptor
- if !rule.IsMatchSet() {
- pbDesc := new(rlsconfv3.RateLimitDescriptor)
- // GenericKey case
- pbDesc.Key = getRouteRuleDescriptor(rIdx, -1)
- pbDesc.Value = getRouteRuleDescriptor(rIdx, -1)
- rateLimit := rlsconfv3.RateLimitPolicy{
- RequestsPerUnit: uint32(rule.Limit.Requests),
- Unit: rlsconfv3.RateLimitUnit(rlsconfv3.RateLimitUnit_value[strings.ToUpper(string(rule.Limit.Unit))]),
- }
- pbDesc.RateLimit = &rateLimit
- head = pbDesc
- cur = head
+ rateLimitPolicy := &rlsconfv3.RateLimitPolicy{
+ RequestsPerUnit: uint32(rule.Limit.Requests),
+ Unit: rlsconfv3.RateLimitUnit(rlsconfv3.RateLimitUnit_value[strings.ToUpper(string(rule.Limit.Unit))]),
}
+ // We use a chain structure to describe the matching descriptors for one rule.
+ // The RateLimitPolicy should be added to the last descriptor in the chain.
+ var head, cur *rlsconfv3.RateLimitDescriptor
+
for mIdx, match := range rule.HeaderMatches {
pbDesc := new(rlsconfv3.RateLimitDescriptor)
// Case for distinct match
@@ -357,15 +359,6 @@ func buildRateLimitServiceDescriptors(global *ir.GlobalRateLimit) []*rlsconfv3.R
pbDesc.Value = getRouteRuleDescriptor(rIdx, mIdx)
}
- // Add the ratelimit values to the last descriptor
- if mIdx == len(rule.HeaderMatches)-1 {
- rateLimit := rlsconfv3.RateLimitPolicy{
- RequestsPerUnit: uint32(rule.Limit.Requests),
- Unit: rlsconfv3.RateLimitUnit(rlsconfv3.RateLimitUnit_value[strings.ToUpper(string(rule.Limit.Unit))]),
- }
- pbDesc.RateLimit = &rateLimit
- }
-
if mIdx == 0 {
head = pbDesc
} else {
@@ -373,6 +366,9 @@ func buildRateLimitServiceDescriptors(global *ir.GlobalRateLimit) []*rlsconfv3.R
}
cur = pbDesc
+
+ // Do not add the RateLimitPolicy to the last header match descriptor yet,
+ // as it is also possible that CIDR match descriptor also exist.
}
// EG supports two kinds of rate limit descriptors for the source IP: exact and distinct.
@@ -401,25 +397,37 @@ func buildRateLimitServiceDescriptors(global *ir.GlobalRateLimit) []*rlsconfv3.R
pbDesc := new(rlsconfv3.RateLimitDescriptor)
pbDesc.Key = "masked_remote_address"
pbDesc.Value = rule.CIDRMatch.CIDR
- rateLimit := rlsconfv3.RateLimitPolicy{
- RequestsPerUnit: uint32(rule.Limit.Requests),
- Unit: rlsconfv3.RateLimitUnit(rlsconfv3.RateLimitUnit_value[strings.ToUpper(string(rule.Limit.Unit))]),
+
+ if cur != nil {
+ // The header match descriptor chain exist, add current
+ // descriptor to the chain.
+ cur.Descriptors = []*rlsconfv3.RateLimitDescriptor{pbDesc}
+ } else {
+ head = pbDesc
}
+ cur = pbDesc
if rule.CIDRMatch.Distinct {
- pbDesc.Descriptors = []*rlsconfv3.RateLimitDescriptor{
- {
- Key: "remote_address",
- RateLimit: &rateLimit,
- },
- }
- } else {
- pbDesc.RateLimit = &rateLimit
+ pbDesc := new(rlsconfv3.RateLimitDescriptor)
+ pbDesc.Key = "remote_address"
+ cur.Descriptors = []*rlsconfv3.RateLimitDescriptor{pbDesc}
+ cur = pbDesc
}
+ }
+
+ // Case when both header and cidr match are not set and the ratelimit
+ // will be applied to all traffic.
+ if !rule.IsMatchSet() {
+ pbDesc := new(rlsconfv3.RateLimitDescriptor)
+ // GenericKey case
+ pbDesc.Key = getRouteRuleDescriptor(rIdx, -1)
+ pbDesc.Value = getRouteRuleDescriptor(rIdx, -1)
head = pbDesc
cur = head
}
+ // Add the ratelimit policy to the last descriptor of chain.
+ cur.RateLimit = rateLimitPolicy
pbDescriptors = append(pbDescriptors, head)
}
@@ -483,17 +491,13 @@ func (t *Translator) createRateLimitServiceCluster(tCtx *types.ResourceVersionTa
return err
}
- if err := addXdsCluster(tCtx, &xdsClusterArgs{
+ return addXdsCluster(tCtx, &xdsClusterArgs{
name: clusterName,
settings: []*ir.DestinationSetting{ds},
tSocket: tSocket,
endpointType: EndpointTypeDNS,
metrics: metrics,
- }); err != nil && !errors.Is(err, ErrXdsClusterExists) {
- return err
- }
-
- return nil
+ })
}
func getRouteRuleDescriptor(ruleIndex, matchIndex int) string {
diff --git a/internal/xds/translator/route.go b/internal/xds/translator/route.go
index 2b9c75a2e91..414e76b8366 100644
--- a/internal/xds/translator/route.go
+++ b/internal/xds/translator/route.go
@@ -16,6 +16,7 @@ import (
matcherv3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/wrapperspb"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils/protocov"
@@ -96,12 +97,11 @@ func buildXdsRoute(httpRoute *ir.HTTPRoute) (*routev3.Route, error) {
}
// Timeouts
- if router.GetRoute() != nil &&
- httpRoute.Traffic != nil &&
- httpRoute.Traffic.Timeout != nil &&
- httpRoute.Traffic.Timeout.HTTP != nil &&
- httpRoute.Traffic.Timeout.HTTP.RequestTimeout != nil {
- router.GetRoute().Timeout = durationpb.New(httpRoute.Traffic.Timeout.HTTP.RequestTimeout.Duration)
+ if router.GetRoute() != nil {
+ rt := getEffectiveRequestTimeout(httpRoute)
+ if rt != nil {
+ router.GetRoute().Timeout = durationpb.New(rt.Duration)
+ }
}
// Retries
@@ -244,39 +244,33 @@ func buildXdsWeightedRouteAction(backendWeights *ir.BackendWeights, settings []*
Weight: &wrapperspb.UInt32Value{Value: backendWeights.Invalid},
}
weightedClusters = append(weightedClusters, invalidCluster)
- return &routev3.RouteAction{
- // Intentionally route to a non-existent cluster and return a 500 error when it is not found
- ClusterNotFoundResponseCode: routev3.RouteAction_INTERNAL_SERVER_ERROR,
- ClusterSpecifier: &routev3.RouteAction_WeightedClusters{
- WeightedClusters: &routev3.WeightedCluster{
- Clusters: weightedClusters,
- },
- },
- }
}
for _, destinationSetting := range settings {
- if destinationSetting.Filters != nil {
+ if len(destinationSetting.Endpoints) > 0 {
validCluster := &routev3.WeightedCluster_ClusterWeight{
Name: backendWeights.Name,
Weight: &wrapperspb.UInt32Value{Value: *destinationSetting.Weight},
}
- if len(destinationSetting.Filters.AddRequestHeaders) > 0 {
- validCluster.RequestHeadersToAdd = append(validCluster.RequestHeadersToAdd, buildXdsAddedHeaders(destinationSetting.Filters.AddRequestHeaders)...)
- }
+ if destinationSetting.Filters != nil {
+ if len(destinationSetting.Filters.AddRequestHeaders) > 0 {
+ validCluster.RequestHeadersToAdd = append(validCluster.RequestHeadersToAdd, buildXdsAddedHeaders(destinationSetting.Filters.AddRequestHeaders)...)
+ }
- if len(destinationSetting.Filters.RemoveRequestHeaders) > 0 {
- validCluster.RequestHeadersToRemove = append(validCluster.RequestHeadersToRemove, destinationSetting.Filters.RemoveRequestHeaders...)
- }
+ if len(destinationSetting.Filters.RemoveRequestHeaders) > 0 {
+ validCluster.RequestHeadersToRemove = append(validCluster.RequestHeadersToRemove, destinationSetting.Filters.RemoveRequestHeaders...)
+ }
- if len(destinationSetting.Filters.AddResponseHeaders) > 0 {
- validCluster.ResponseHeadersToAdd = append(validCluster.ResponseHeadersToAdd, buildXdsAddedHeaders(destinationSetting.Filters.AddResponseHeaders)...)
- }
+ if len(destinationSetting.Filters.AddResponseHeaders) > 0 {
+ validCluster.ResponseHeadersToAdd = append(validCluster.ResponseHeadersToAdd, buildXdsAddedHeaders(destinationSetting.Filters.AddResponseHeaders)...)
+ }
- if len(destinationSetting.Filters.RemoveResponseHeaders) > 0 {
- validCluster.ResponseHeadersToRemove = append(validCluster.ResponseHeadersToRemove, destinationSetting.Filters.RemoveResponseHeaders...)
+ if len(destinationSetting.Filters.RemoveResponseHeaders) > 0 {
+ validCluster.ResponseHeadersToRemove = append(validCluster.ResponseHeadersToRemove, destinationSetting.Filters.RemoveResponseHeaders...)
+ }
}
+
weightedClusters = append(weightedClusters, validCluster)
}
}
@@ -292,14 +286,26 @@ func buildXdsWeightedRouteAction(backendWeights *ir.BackendWeights, settings []*
}
}
-func idleTimeout(httpRoute *ir.HTTPRoute) *durationpb.Duration {
+func getEffectiveRequestTimeout(httpRoute *ir.HTTPRoute) *metav1.Duration {
+ // gateway-api timeout takes precedence
+ if httpRoute.Timeout != nil {
+ return httpRoute.Timeout
+ }
+
if httpRoute.Traffic != nil &&
httpRoute.Traffic.Timeout != nil &&
httpRoute.Traffic.Timeout.HTTP != nil &&
httpRoute.Traffic.Timeout.HTTP.RequestTimeout != nil {
- rt := httpRoute.Traffic.Timeout.HTTP.RequestTimeout
- timeout := time.Hour // Default to 1 hour
+ return httpRoute.Traffic.Timeout.HTTP.RequestTimeout
+ }
+
+ return nil
+}
+func idleTimeout(httpRoute *ir.HTTPRoute) *durationpb.Duration {
+ rt := getEffectiveRequestTimeout(httpRoute)
+ timeout := time.Hour // Default to 1 hour
+ if rt != nil {
// Ensure is not less than the request timeout
if timeout < rt.Duration {
timeout = rt.Duration
@@ -386,14 +392,15 @@ func buildXdsURLRewriteAction(destName string, urlRewrite *ir.URLRewrite, pathMa
}
if urlRewrite.Path != nil {
- if urlRewrite.Path.FullReplace != nil {
+ switch {
+ case urlRewrite.Path.FullReplace != nil:
routeAction.RegexRewrite = &matcherv3.RegexMatchAndSubstitute{
Pattern: &matcherv3.RegexMatcher{
Regex: "^/.*$",
},
Substitution: *urlRewrite.Path.FullReplace,
}
- } else if urlRewrite.Path.PrefixMatchReplace != nil {
+ case urlRewrite.Path.PrefixMatchReplace != nil:
// Circumvent the case of "//" when the replace string is "/"
// An empty replace string does not seem to solve the issue so we are using
// a regex match and replace instead
@@ -401,14 +408,36 @@ func buildXdsURLRewriteAction(destName string, urlRewrite *ir.URLRewrite, pathMa
if useRegexRewriteForPrefixMatchReplace(pathMatch, *urlRewrite.Path.PrefixMatchReplace) {
routeAction.RegexRewrite = prefix2RegexRewrite(*pathMatch.Prefix)
} else {
- routeAction.PrefixRewrite = *urlRewrite.Path.PrefixMatchReplace
+ // remove trailing / to fix #3989
+ // when the pathMath.Prefix has suffix / but EG has removed it,
+ // and the urlRewrite.Path.PrefixMatchReplace suffix with / the upstream will get unwanted /
+ routeAction.PrefixRewrite = strings.TrimSuffix(*urlRewrite.Path.PrefixMatchReplace, "/")
+ }
+ case urlRewrite.Path.RegexMatchReplace != nil:
+ routeAction.RegexRewrite = &matcherv3.RegexMatchAndSubstitute{
+ Pattern: &matcherv3.RegexMatcher{
+ Regex: urlRewrite.Path.RegexMatchReplace.Pattern,
+ },
+ Substitution: urlRewrite.Path.RegexMatchReplace.Substitution,
}
}
}
- if urlRewrite.Hostname != nil {
- routeAction.HostRewriteSpecifier = &routev3.RouteAction_HostRewriteLiteral{
- HostRewriteLiteral: *urlRewrite.Hostname,
+ if urlRewrite.Host != nil {
+
+ switch {
+ case urlRewrite.Host.Name != nil:
+ routeAction.HostRewriteSpecifier = &routev3.RouteAction_HostRewriteLiteral{
+ HostRewriteLiteral: *urlRewrite.Host.Name,
+ }
+ case urlRewrite.Host.Header != nil:
+ routeAction.HostRewriteSpecifier = &routev3.RouteAction_HostRewriteHeader{
+ HostRewriteHeader: *urlRewrite.Host.Header,
+ }
+ case urlRewrite.Host.Backend != nil:
+ routeAction.HostRewriteSpecifier = &routev3.RouteAction_AutoHostRewrite{
+ AutoHostRewrite: wrapperspb.Bool(true),
+ }
}
routeAction.AppendXForwardedHost = true
@@ -417,8 +446,20 @@ func buildXdsURLRewriteAction(destName string, urlRewrite *ir.URLRewrite, pathMa
return routeAction
}
-func buildXdsDirectResponseAction(res *ir.DirectResponse) *routev3.DirectResponseAction {
- routeAction := &routev3.DirectResponseAction{Status: res.StatusCode}
+func buildXdsDirectResponseAction(res *ir.CustomResponse) *routev3.DirectResponseAction {
+ routeAction := &routev3.DirectResponseAction{}
+ if res.StatusCode != nil {
+ routeAction.Status = *res.StatusCode
+ }
+
+ if res.Body != nil && *res.Body != "" {
+ routeAction.Body = &corev3.DataSource{
+ Specifier: &corev3.DataSource_InlineString{
+ InlineString: *res.Body,
+ },
+ }
+ }
+
return routeAction
}
@@ -435,9 +476,9 @@ func buildXdsRequestMirrorPolicies(mirrorDestinations []*ir.RouteDestination) []
}
func buildXdsAddedHeaders(headersToAdd []ir.AddHeader) []*corev3.HeaderValueOption {
- headerValueOptions := make([]*corev3.HeaderValueOption, len(headersToAdd))
+ headerValueOptions := []*corev3.HeaderValueOption{}
- for i, header := range headersToAdd {
+ for _, header := range headersToAdd {
var appendAction corev3.HeaderValueOption_HeaderAppendAction
if header.Append {
@@ -445,18 +486,26 @@ func buildXdsAddedHeaders(headersToAdd []ir.AddHeader) []*corev3.HeaderValueOpti
} else {
appendAction = corev3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD
}
-
- headerValueOptions[i] = &corev3.HeaderValueOption{
- Header: &corev3.HeaderValue{
- Key: header.Name,
- Value: header.Value,
- },
- AppendAction: appendAction,
- }
-
// Allow empty headers to be set, but don't add the config to do so unless necessary
- if header.Value == "" {
- headerValueOptions[i].KeepEmptyValue = true
+ if len(header.Value) == 0 {
+ headerValueOptions = append(headerValueOptions, &corev3.HeaderValueOption{
+ Header: &corev3.HeaderValue{
+ Key: header.Name,
+ },
+ AppendAction: appendAction,
+ KeepEmptyValue: true,
+ })
+ } else {
+ for _, val := range header.Value {
+ headerValueOptions = append(headerValueOptions, &corev3.HeaderValueOption{
+ Header: &corev3.HeaderValue{
+ Key: header.Name,
+ Value: val,
+ },
+ AppendAction: appendAction,
+ KeepEmptyValue: val == "",
+ })
+ }
}
}
@@ -545,7 +594,7 @@ func buildRetryPolicy(route *ir.HTTPRoute) (*routev3.RetryPolicy, error) {
}
if rr.RetryOn != nil {
- if rr.RetryOn.Triggers != nil && len(rr.RetryOn.Triggers) > 0 {
+ if len(rr.RetryOn.Triggers) > 0 {
if ro, err := buildRetryOn(rr.RetryOn.Triggers); err == nil {
rp.RetryOn = ro
} else {
@@ -553,7 +602,7 @@ func buildRetryPolicy(route *ir.HTTPRoute) (*routev3.RetryPolicy, error) {
}
}
- if rr.RetryOn.HTTPStatusCodes != nil && len(rr.RetryOn.HTTPStatusCodes) > 0 {
+ if len(rr.RetryOn.HTTPStatusCodes) > 0 {
rp.RetriableStatusCodes = buildRetryStatusCodes(rr.RetryOn.HTTPStatusCodes)
}
}
diff --git a/internal/xds/translator/session_persistence.go b/internal/xds/translator/session_persistence.go
new file mode 100644
index 00000000000..703e553ce47
--- /dev/null
+++ b/internal/xds/translator/session_persistence.go
@@ -0,0 +1,169 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package translator
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
+ routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
+ statefulsessionv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/stateful_session/v3"
+ hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
+ cookiev3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/cookie/v3"
+ headerv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/header/v3"
+ httpv3 "github.com/envoyproxy/go-control-plane/envoy/type/http/v3"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/anypb"
+ "google.golang.org/protobuf/types/known/durationpb"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/xds/types"
+)
+
+const (
+ cookieConfigName = "envoy.http.stateful_session.cookie"
+ headerConfigName = "envoy.http.stateful_session.header"
+)
+
+type sessionPersistence struct{}
+
+func init() {
+ registerHTTPFilter(&sessionPersistence{})
+}
+
+var _ httpFilter = &sessionPersistence{}
+
+// patchHCM patches the HttpConnectionManager with the filter.
+// Note: this method may be called multiple times for the same filter, please
+// make sure to avoid duplicate additions of the same filter.
+func (s *sessionPersistence) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error {
+ if mgr == nil {
+ return errors.New("hcm is nil")
+ }
+
+ if irListener == nil {
+ return errors.New("ir listener is nil")
+ }
+
+ for _, route := range irListener.Routes {
+ sp := route.SessionPersistence
+ if sp == nil {
+ continue
+ }
+
+ if hcmContainsFilter(mgr, perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name)) {
+ continue
+ }
+
+ var sessionCfg proto.Message
+ var configName string
+ switch {
+ case sp.Cookie != nil:
+ configName = cookieConfigName
+ sessionCfg = &cookiev3.CookieBasedSessionState{
+ Cookie: &httpv3.Cookie{
+ Name: sp.Cookie.Name,
+ Path: routePathToCookiePath(route.PathMatch),
+ Ttl: durationpb.New(sp.Cookie.TTL.Duration),
+ },
+ }
+ case sp.Header != nil:
+ configName = headerConfigName
+ sessionCfg = &headerv3.HeaderBasedSessionState{
+ Name: sp.Header.Name,
+ }
+ }
+
+ sessionCfgAny, err := anypb.New(sessionCfg)
+ if err != nil {
+ return fmt.Errorf("failed to marshal %s config: %w", egv1a1.EnvoyFilterSessionPersistence.String(), err)
+ }
+
+ cfg := &statefulsessionv3.StatefulSession{
+ SessionState: &corev3.TypedExtensionConfig{
+ Name: configName,
+ TypedConfig: sessionCfgAny,
+ },
+ }
+
+ cfgAny, err := anypb.New(cfg)
+ if err != nil {
+ return fmt.Errorf("failed to marshal %s config: %w", egv1a1.EnvoyFilterSessionPersistence.String(), err)
+ }
+
+ mgr.HttpFilters = append(mgr.HttpFilters, &hcmv3.HttpFilter{
+ Name: perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name),
+ Disabled: true,
+ ConfigType: &hcmv3.HttpFilter_TypedConfig{
+ TypedConfig: cfgAny,
+ },
+ })
+ }
+
+ return nil
+}
+
+func routePathToCookiePath(path *ir.StringMatch) string {
+ if path == nil {
+ return "/"
+ }
+ switch {
+ case path.Exact != nil:
+ return *path.Exact
+ case path.Prefix != nil:
+ return *path.Prefix
+ case path.SafeRegex != nil:
+ return getLongestNonRegexPrefix(*path.SafeRegex)
+ }
+
+ // Shouldn't reach here because the path should be either of the above three kinds.
+ return "/"
+}
+
+// getLongestNonRegexPrefix takes a regex path and returns the longest non-regex prefix.
+// > 3. For an xRoute using a path that is a regex, the Path should be set to the longest non-regex prefix
+// (.e.g. if the path is /p1/p2/*/p3 and the request path was /p1/p2/foo/p3, then the cookie path would be /p1/p2).
+// https://gateway-api.sigs.k8s.io/geps/gep-1619/#path
+func getLongestNonRegexPrefix(path string) string {
+ parts := strings.Split(path, "/")
+ var longestNonRegexPrefix []string
+ for _, part := range parts {
+ if part == "*" || strings.Contains(part, "*") {
+ break
+ }
+ longestNonRegexPrefix = append(longestNonRegexPrefix, part)
+ }
+
+ return strings.Join(longestNonRegexPrefix, "/")
+}
+
+// patchRoute patches the provide Route with a filter's Route level configuration.
+func (s *sessionPersistence) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
+ if route == nil {
+ return errors.New("xds route is nil")
+ }
+ if irRoute == nil {
+ return errors.New("ir route is nil")
+ }
+ if irRoute.SessionPersistence == nil {
+ return nil
+ }
+
+ if err := enableFilterOnRoute(route, perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name)); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// patchResources adds all the other needed resources referenced by this
+// filter to the resource version table.
+func (s *sessionPersistence) patchResources(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRoute) error {
+ return nil
+}
diff --git a/internal/xds/translator/testdata/in/extension-xds-ir/extensionpolicy-tcp-udp-http.yaml b/internal/xds/translator/testdata/in/extension-xds-ir/extensionpolicy-tcp-udp-http.yaml
index 77ced570f46..6a5d283ee44 100644
--- a/internal/xds/translator/testdata/in/extension-xds-ir/extensionpolicy-tcp-udp-http.yaml
+++ b/internal/xds/translator/testdata/in/extension-xds-ir/extensionpolicy-tcp-udp-http.yaml
@@ -35,6 +35,15 @@ http:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 10080
+ routes:
+ - name: "http-route"
+ hostname: "*"
+ destination:
+ name: "http-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
tcp:
- address: 0.0.0.0
extensionRefs:
@@ -66,6 +75,13 @@ tcp:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
name: envoy-gateway/gateway-1/tcp1
port: 10080
+ routes:
+ - destination:
+ name: "tcp-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
udp:
- address: 0.0.0.0
route:
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/header-and-cidr-matches.yaml b/internal/xds/translator/testdata/in/ratelimit-config/header-and-cidr-matches.yaml
new file mode 100644
index 00000000000..481b8598695
--- /dev/null
+++ b/internal/xds/translator/testdata/in/ratelimit-config/header-and-cidr-matches.yaml
@@ -0,0 +1,38 @@
+name: "first-listener"
+address: "0.0.0.0"
+port: 10080
+hostnames:
+- "*"
+path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+routes:
+- name: "first-route"
+ traffic:
+ rateLimit:
+ global:
+ rules:
+ - headerMatches:
+ - name: "x-user-id"
+ exact: "one"
+ - name: "x-user-id"
+ exact: "two"
+ - name: "x-org-id"
+ exact: "three"
+ cidrMatch:
+ cidr: 0.0.0.0/0
+ ip: 0.0.0.0
+ maskLen: 0
+ isIPv6: false
+ distinct: false
+ limit:
+ requests: 5
+ unit: second
+ pathMatch:
+ exact: "foo/bar"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml
index 2d8f0c6aa48..4b437f443e8 100644
--- a/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml
@@ -17,6 +17,27 @@ accesslog:
port: 9000
protocol: GRPC
weight: 1
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ baseEjectionTime: 30s
+ consecutiveGatewayErrors: 4
+ consecutive5XxErrors: 5
+ consecutiveLocalOriginFailures: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ splitExternalLocalOriginErrors: false
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
attributes:
attr1: value1
attr2: value2
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-cel.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-cel.yaml
index e9cff901d3d..8a0497c3fb8 100644
--- a/internal/xds/translator/testdata/in/xds-ir/accesslog-cel.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-cel.yaml
@@ -35,7 +35,7 @@ accesslog:
protocol: "GRPC"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -51,6 +51,3 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
- directResponse:
- body: "Unknown custom filter type: UnsupportedType"
- statusCode: 500
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml
index b5244667de9..623c3b6d594 100644
--- a/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml
@@ -31,7 +31,7 @@ accesslog:
protocol: "GRPC"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -47,6 +47,3 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
- directResponse:
- body: "Unknown custom filter type: UnsupportedType"
- statusCode: 500
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml
index 7c1024879d8..4ba42ea82bb 100644
--- a/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml
@@ -39,7 +39,7 @@ accesslog:
protocol: "GRPC"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -55,6 +55,3 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
- directResponse:
- body: "Unknown custom filter type: UnsupportedType"
- statusCode: 500
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-invalid.yaml
index 10768da4354..8c8161e2e33 100644
--- a/internal/xds/translator/testdata/in/xds-ir/accesslog-invalid.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-invalid.yaml
@@ -27,7 +27,7 @@ accesslog:
port: 4317
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-multi-cel.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-multi-cel.yaml
index fab193fe564..d84151866f2 100644
--- a/internal/xds/translator/testdata/in/xds-ir/accesslog-multi-cel.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-multi-cel.yaml
@@ -39,7 +39,7 @@ accesslog:
protocol: "GRPC"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -55,6 +55,3 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
- directResponse:
- body: "Unknown custom filter type: UnsupportedType"
- statusCode: 500
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-types.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-types.yaml
new file mode 100644
index 00000000000..b42a839f018
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-types.yaml
@@ -0,0 +1,181 @@
+accessLog:
+ als:
+ - destination:
+ name: accesslog_als_0_1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ logType: Route
+ name: accesslog
+ text: |
+ this is a route log
+ type: HTTP
+ - destination:
+ name: accesslog_als_0_2
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ logType: Route
+ name: envoy-gateway-system/test
+ text: |
+ this is a route log
+ type: TCP
+ - destination:
+ name: accesslog_als_1_1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ logType: Listener
+ name: accesslog
+ text: |
+ this is a listener log
+ type: HTTP
+ - destination:
+ name: accesslog_als_1_2
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ logType: Listener
+ name: envoy-gateway-system/test
+ text: |
+ this is a listener log
+ type: TCP
+ - destination:
+ name: accesslog_als_2_1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ name: accesslog
+ text: |
+ this is a Global log
+ type: HTTP
+ - destination:
+ name: accesslog_als_2_2
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ name: envoy-gateway-system/test
+ text: |
+ this is a Global log
+ type: TCP
+ openTelemetry:
+ - authority: otel-collector.monitoring.svc.cluster.local
+ destination:
+ name: accesslog_otel_0_3
+ settings:
+ - endpoints:
+ - host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ protocol: GRPC
+ weight: 1
+ logType: Route
+ resources:
+ k8s.cluster.name: cluster-1
+ text: |
+ this is a route log
+ - authority: otel-collector.monitoring.svc.cluster.local
+ destination:
+ name: accesslog_otel_1_3
+ settings:
+ - endpoints:
+ - host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ protocol: GRPC
+ weight: 1
+ logType: Listener
+ resources:
+ k8s.cluster.name: cluster-1
+ text: |
+ this is a listener log
+ - authority: otel-collector.monitoring.svc.cluster.local
+ destination:
+ name: accesslog_otel_2_3
+ settings:
+ - endpoints:
+ - host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ protocol: GRPC
+ weight: 1
+ resources:
+ k8s.cluster.name: cluster-1
+ text: |
+ this is a Global log
+ text:
+ - logType: Route
+ path: /dev/stdout
+ - logType: Listener
+ path: /dev/stdout
+ - format: |
+ this is a route log
+ logType: Route
+ path: /dev/stdout
+ - format: |
+ this is a listener log
+ logType: Listener
+ path: /dev/stdout
+ - format: |
+ this is a Global log
+ path: /dev/stdout
+http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - name: "direct-route"
+ hostname: "*"
+ destination:
+ name: "direct-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-without-format.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-without-format.yaml
index 40aef558e3e..1492b397569 100644
--- a/internal/xds/translator/testdata/in/xds-ir/accesslog-without-format.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-without-format.yaml
@@ -11,7 +11,8 @@ accesslog:
protocol: "%PROTOCOL%"
response_code: "%RESPONSE_CODE%"
als:
- - destination:
+ - name: als
+ destination:
name: accesslog/monitoring/envoy-als/port/9000
settings:
- addressType: IP
@@ -43,7 +44,7 @@ accesslog:
protocol: "GRPC"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -59,6 +60,3 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
- directResponse:
- body: "Unknown custom filter type: UnsupportedType"
- statusCode: 500
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml
index 26f0f5663f8..38d5e8a74be 100644
--- a/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml
@@ -13,7 +13,8 @@ accesslog:
protocol: "%PROTOCOL%"
response_code: "%RESPONSE_CODE%"
als:
- - destination:
+ - name: als
+ destination:
name: accesslog/monitoring/envoy-als/port/9000
settings:
- addressType: IP
@@ -52,7 +53,7 @@ accesslog:
protocol: "GRPC"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -68,6 +69,3 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
- directResponse:
- body: "Unknown custom filter type: UnsupportedType"
- statusCode: 500
diff --git a/internal/xds/translator/testdata/in/xds-ir/authorization.yaml b/internal/xds/translator/testdata/in/xds-ir/authorization-client-cidr.yaml
similarity index 100%
rename from internal/xds/translator/testdata/in/xds-ir/authorization.yaml
rename to internal/xds/translator/testdata/in/xds-ir/authorization-client-cidr.yaml
diff --git a/internal/xds/translator/testdata/in/xds-ir/authorization-jwt-claim.yaml b/internal/xds/translator/testdata/in/xds-ir/authorization-jwt-claim.yaml
new file mode 100644
index 00000000000..f952f20cc26
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/authorization-jwt-claim.yaml
@@ -0,0 +1,99 @@
+http:
+- address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ security:
+ authorization:
+ defaultAction: Deny
+ rules:
+ - action: Deny
+ name: allow-claim-roles
+ principal:
+ jwt:
+ provider: example1
+ claims:
+ - name: user.name
+ values: ["alice", "bob"]
+ jwt:
+ providers:
+ - audiences:
+ - two.foo.com
+ issuer: https://two.example.com
+ name: example1
+ remoteJWKS:
+ uri: https://two.example.com/jwt/public-key/jwks.json
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
+ security:
+ authorization:
+ defaultAction: Deny
+ rules:
+ - action: Deny
+ name: allow-claim-roles
+ principal:
+ jwt:
+ provider: example1
+ claims:
+ - name: roles
+ valueType: StringArray
+ values: ["admin", "superuser"]
+ - name: department
+ values: ["engineering"]
+ jwt:
+ providers:
+ - audiences:
+ - one.foo.com
+ issuer: https://one.example.com
+ name: example1
+ remoteJWKS:
+ uri: https://one.example.com/jwt/public-key/jwks.json
diff --git a/internal/xds/translator/testdata/in/xds-ir/authorization-jwt-scope.yaml b/internal/xds/translator/testdata/in/xds-ir/authorization-jwt-scope.yaml
new file mode 100644
index 00000000000..332060147c4
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/authorization-jwt-scope.yaml
@@ -0,0 +1,95 @@
+http:
+- address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ security:
+ authorization:
+ defaultAction: Deny
+ rules:
+ - action: Deny
+ name: allow-scope-foo-bar
+ principal:
+ jwt:
+ provider: example1
+ scopes:
+ - foo
+ - bar
+ jwt:
+ providers:
+ - audiences:
+ - two.foo.com
+ issuer: https://two.example.com
+ name: example1
+ remoteJWKS:
+ uri: https://two.example.com/jwt/public-key/jwks.json
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
+ security:
+ authorization:
+ defaultAction: Deny
+ rules:
+ - action: Deny
+ name: allow-scope-foo
+ principal:
+ jwt:
+ provider: example1
+ scopes:
+ - foo
+ jwt:
+ providers:
+ - audiences:
+ - one.foo.com
+ issuer: https://one.example.com
+ name: example1
+ remoteJWKS:
+ uri: https://one.example.com/jwt/public-key/jwks.json
diff --git a/internal/xds/translator/testdata/in/xds-ir/authorization-multiple-principals.yaml b/internal/xds/translator/testdata/in/xds-ir/authorization-multiple-principals.yaml
new file mode 100644
index 00000000000..8b83e16d556
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/authorization-multiple-principals.yaml
@@ -0,0 +1,80 @@
+http:
+- address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.example.com
+ isHTTP2: false
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ security:
+ authorization:
+ defaultAction: Deny
+ rules:
+ - action: Allow
+ name: allow-rule-1
+ principal:
+ clientCIDRs:
+ - cidr: 192.168.1.0/24
+ distinct: false
+ ip: 192.168.1.0
+ isIPv6: false
+ maskLen: 24
+ - cidr: 192.168.2.0/24
+ distinct: false
+ ip: 192.168.2.0
+ isIPv6: false
+ maskLen: 24
+ jwt:
+ provider: https://one.example.com
+ scopes:
+ - foo
+ claims:
+ - name: roles
+ valueType: StringArray
+ values: ["admin", "superuser"]
+ - name: department
+ values: ["engineering"]
+ - action: Allow
+ name: allow-rule-2
+ principal:
+ clientCIDRs:
+ - cidr: 10.0.1.0/24
+ distinct: false
+ ip: 10.0.1.0
+ isIPv6: false
+ maskLen: 24
+ - cidr: 10.0.2.0/24
+ distinct: false
+ ip: 10.0.2.0
+ isIPv6: false
+ maskLen: 24
+ jwt:
+ provider: https://two.example.com
+ scopes:
+ - for
+ - bar
+ claims:
+ - name: roles
+ valueType: StringArray
+ values: ["admin", "superuser"]
+ - name: name
+ values: ["alice", "bob"]
diff --git a/internal/xds/translator/testdata/in/xds-ir/backend-buffer-limit.yaml b/internal/xds/translator/testdata/in/xds-ir/backend-buffer-limit.yaml
index 493180389ad..4cb9541775b 100644
--- a/internal/xds/translator/testdata/in/xds-ir/backend-buffer-limit.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/backend-buffer-limit.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -21,7 +21,7 @@ http:
bufferLimit: 100000000
tcp:
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
connection:
bufferLimit: 1500
port: 10081
@@ -37,7 +37,7 @@ tcp:
bufferLimit: 100000000
udp:
- name: "udp-route"
- address: "0.0.0.0"
+ address: "::"
port: 10080
route:
name: "udp-route"
diff --git a/internal/xds/translator/testdata/in/xds-ir/backend-priority.yaml b/internal/xds/translator/testdata/in/xds-ir/backend-priority.yaml
new file mode 100644
index 00000000000..b18671d7879
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/backend-priority.yaml
@@ -0,0 +1,97 @@
+http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ envoyExtensions:
+ extProcs:
+ - authority: grpc-backend.envoy-gateway:8000
+ destination:
+ name: envoyextensionpolicy/default/policy-for-http-route/0
+ settings:
+ - addressType: IP
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-grpc/envoy-gateway-ca
+ sni: grpc-backend
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 9000
+ priority: 1
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ priority: 1
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3443
+ priority: 1
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sni: ip-backend
+ weight: 1
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml b/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml
index f4dd3bbaa99..1eb6f7b7010 100644
--- a/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/client-buffer-limit.yaml b/internal/xds/translator/testdata/in/xds-ir/client-buffer-limit.yaml
index c7af759ecf9..6604d37dc47 100644
--- a/internal/xds/translator/testdata/in/xds-ir/client-buffer-limit.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/client-buffer-limit.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -20,7 +20,7 @@ http:
bufferLimit: 1500
tcp:
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
connection:
bufferLimit: 1500
port: 10081
diff --git a/internal/xds/translator/testdata/in/xds-ir/client-ip-detection.yaml b/internal/xds/translator/testdata/in/xds-ir/client-ip-detection.yaml
index de3236a8622..1894902a0ba 100644
--- a/internal/xds/translator/testdata/in/xds-ir/client-ip-detection.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/client-ip-detection.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 8081
hostnames:
- "*"
@@ -17,7 +17,7 @@ http:
xForwardedFor:
numTrustedHops: 2
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 8082
hostnames:
- "*"
@@ -35,7 +35,7 @@ http:
name: "x-my-custom-header"
failClosed: false
- name: "third-listener"
- address: "0.0.0.0"
+ address: "::"
port: 8083
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml b/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml
index 741f2d46451..6ce11179029 100644
--- a/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -22,7 +22,7 @@ http:
idleTimeout: "10s"
tcp:
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10081
routes:
- name: "second-route"
diff --git a/internal/xds/translator/testdata/in/xds-ir/cors.yaml b/internal/xds/translator/testdata/in/xds-ir/cors.yaml
index dd9eff3418f..2d7fedf0513 100644
--- a/internal/xds/translator/testdata/in/xds-ir/cors.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/cors.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -30,6 +30,7 @@ http:
allowMethods:
- GET
- POST
+ - "*"
allowHeaders:
- "x-header-1"
- "x-header-2"
diff --git a/internal/xds/translator/testdata/in/xds-ir/custom-response.yaml b/internal/xds/translator/testdata/in/xds-ir/custom-response.yaml
new file mode 100644
index 00000000000..cb00ac65af9
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/custom-response.yaml
@@ -0,0 +1,56 @@
+http:
+ - address: 0.0.0.0
+ hostnames:
+ - "*"
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: "*"
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/-1/*
+ traffic:
+ responseOverride:
+ name: backendtrafficpolicy/default/policy-for-gateway
+ rules:
+ - match:
+ statusCodes:
+ - value: 404
+ name: backendtrafficpolicy/default/policy-for-gateway/responseoverride/rule/0
+ response:
+ body: gateway-1 Not Found
+ contentType: text/plain
+ - match:
+ statusCodes:
+ - value: 500
+ - range:
+ end: 511
+ start: 501
+ name: backendtrafficpolicy/default/policy-for-gateway/responseoverride/rule/1
+ response:
+ body: |
+ {
+ "error": "Internal Server Error"
+ }
+ contentType: application/json
diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-auth-backend.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-auth-backend.yaml
new file mode 100644
index 00000000000..4f93e2e7734
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth-backend.yaml
@@ -0,0 +1,123 @@
+http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ hostname: www.foo.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo1
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-http-route-1
+ failOpen: false
+ grpc:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 9000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ - name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ hostname: www.foo.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo2
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-1/rule/1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-http-route-1
+ failOpen: false
+ grpc:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ - name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ hostname: www.bar.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-gateway-1
+ failOpen: true
+ http:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 80
+ protocol: HTTP
+ weight: 1
+ headersToBackend:
+ - header1
+ - header2
+ path: /auth
diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-auth-body.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-auth-body.yaml
new file mode 100644
index 00000000000..f3ce1bd3477
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth-body.yaml
@@ -0,0 +1,125 @@
+http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ hostname: www.foo.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo1
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-http-route-1
+ failOpen: false
+ grpc:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 9000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ - name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ hostname: www.foo.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo2
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-1/rule/1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-http-route-1
+ failOpen: false
+ grpc:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ - name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ hostname: www.bar.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-gateway-1
+ failOpen: true
+ bodyToExtAuth:
+ maxRequestBytes: 32768
+ http:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 80
+ protocol: HTTP
+ weight: 1
+ headersToBackend:
+ - header1
+ - header2
+ path: /auth
diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-auth-recomputation.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-auth-recomputation.yaml
new file mode 100644
index 00000000000..fb0451b9835
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth-recomputation.yaml
@@ -0,0 +1,124 @@
+http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ hostname: www.foo.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo1
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-http-route-1
+ failOpen: false
+ grpc:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 9000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ - name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ hostname: www.foo.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo2
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-1/rule/1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-http-route-1
+ failOpen: false
+ grpc:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ - name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ hostname: www.bar.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-gateway-1
+ failOpen: true
+ recomputeRoute: true
+ http:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 80
+ protocol: HTTP
+ weight: 1
+ headersToBackend:
+ - header1
+ - header2
+ path: /auth
diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml
index bedbbae996c..0453e1341f5 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml
@@ -37,6 +37,12 @@ http:
destination:
name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
settings:
+ - addressType: IP
+ endpoints:
+ - host: 8.8.4.4
+ port: 9001
+ protocol: GRPC
+ weight: 1
- addressType: IP
endpoints:
- host: 8.8.8.8
diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-proc-with-traffic-settings.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-proc-with-traffic-settings.yaml
new file mode 100644
index 00000000000..136fd53ff6a
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/ext-proc-with-traffic-settings.yaml
@@ -0,0 +1,124 @@
+http:
+- address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ envoyExtensions:
+ extProcs:
+ - authority: grpc-backend.envoy-gateway:8000
+ destination:
+ name: envoyextensionpolicy/default/policy-for-http-route/0
+ settings:
+ - addressType: IP
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-grpc/envoy-gateway-ca
+ sni: grpc-backend
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 9000
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3443
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sni: ip-backend
+ weight: 1
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ baseEjectionTime: 30s
+ consecutiveGatewayErrors: 4
+ consecutive5XxErrors: 5
+ consecutiveLocalOriginFailures: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ splitExternalLocalOriginErrors: false
+ http2:
+ initialConnectionWindowSize: 131072
+ initialStreamWindowSize: 2097152
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ loadBalancer:
+ roundRobin:
+ slowStart:
+ window: 5s
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml
index 3fa4cd8bcc7..da4939c228d 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml
@@ -23,8 +23,13 @@ http:
- name: envoyextensionpolicy/default/policy-for-route-2/extproc/0
failOpen: true
messageTimeout: 5s
+ requestAttributes:
+ - xds.route_metadata
+ - connection.requested_server_name
requestHeaderProcessing: true
requestBodyProcessingMode: Buffered
+ responseAttributes:
+ - request.path
responseBodyProcessingMode: Streamed
authority: grpc-backend-4.default:4000
destination:
@@ -71,6 +76,11 @@ http:
- name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0
failOpen: false
messageTimeout: 15s
+ requestAttributes:
+ - xds.route_metadata
+ - connection.requested_server_name
+ responseAttributes:
+ - request.path
authority: grpc-backend.envoy-gateway:9000
destination:
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend
diff --git a/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml b/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml
index 39b351eb6ec..163e3507cae 100644
--- a/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
path:
mergeSlashes: true
diff --git a/internal/xds/translator/testdata/in/xds-ir/headers-with-preserve-x-request-id.yaml b/internal/xds/translator/testdata/in/xds-ir/headers-with-preserve-x-request-id.yaml
index 1376be42e14..d2599bc005c 100644
--- a/internal/xds/translator/testdata/in/xds-ir/headers-with-preserve-x-request-id.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/headers-with-preserve-x-request-id.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 8081
hostnames:
- "*"
@@ -16,7 +16,7 @@ http:
headers:
preserveXRequestID: true
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 8082
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/headers-with-underscores-action.yaml b/internal/xds/translator/testdata/in/xds-ir/headers-with-underscores-action.yaml
index 53b7076925c..0787ec0780a 100644
--- a/internal/xds/translator/testdata/in/xds-ir/headers-with-underscores-action.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/headers-with-underscores-action.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 8081
hostnames:
- "*"
@@ -14,7 +14,7 @@ http:
- host: "1.1.1.1"
port: 8081
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 8082
hostnames:
- "*"
@@ -30,7 +30,7 @@ http:
headers:
withUnderscoresAction: Allow
- name: "third-listener"
- address: "0.0.0.0"
+ address: "::"
port: 8083
hostnames:
- "*"
@@ -46,7 +46,7 @@ http:
headers:
withUnderscoresAction: RejectRequest
- name: "fourth-listener"
- address: "0.0.0.0"
+ address: "::"
port: 8084
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/health-check.yaml b/internal/xds/translator/testdata/in/xds-ir/health-check.yaml
index 30ecd2da792..b78270a421a 100644
--- a/internal/xds/translator/testdata/in/xds-ir/health-check.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/health-check.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
path:
mergeSlashes: true
escapedSlashesAction: UnescapeAndRedirect
@@ -126,3 +126,21 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
+ - name: "fifth-route"
+ hostname: "*"
+ traffic:
+ healthCheck:
+ active:
+ timeout: "1s"
+ interval: "5s"
+ unhealthyThreshold: 3
+ healthyThreshold: 3
+ grpc:
+ service: my-service
+ destination:
+ name: "fifth-route-dest"
+ protocol: GRPC
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-early-header-mutation.yaml b/internal/xds/translator/testdata/in/xds-ir/http-early-header-mutation.yaml
new file mode 100644
index 00000000000..84b0e2f5673
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/http-early-header-mutation.yaml
@@ -0,0 +1,59 @@
+http:
+- name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ http1:
+ preserveHeaderCase: true
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+- name: "second-listener"
+ address: "::"
+ port: 10081
+ hostnames:
+ - "*"
+ headers:
+ earlyAddRequestHeaders:
+ - name: "some-header"
+ value:
+ - "some-value1"
+ - "some-value2"
+ append: true
+ - name: "some-header-2"
+ value:
+ - "some-value"
+ append: true
+ - name: "some-header3"
+ value:
+ - "some-value"
+ append: false
+ - name: "some-header4"
+ value:
+ - "some-value"
+ append: false
+ - name: "empty-header"
+ value:
+ append: false
+ earlyRemoveRequestHeaders:
+ - "some-header5"
+ - "some-header6"
+ routes:
+ - name: "second-route"
+ hostname: "*"
+ destination:
+ name: "second-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.5"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/http-endpoint-stats.yaml
index 12fc177bde8..076e1427e39 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-endpoint-stats.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-endpoint-stats.yaml
@@ -3,7 +3,7 @@ metrics:
enablePerEndpointStats: true
http:
- name: "listener-enable-endpoint-stats"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-health-check.yaml b/internal/xds/translator/testdata/in/xds-ir/http-health-check.yaml
index a4bdd70a384..2a22775b7c0 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-health-check.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-health-check.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-req-resp-sizes-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/http-req-resp-sizes-stats.yaml
new file mode 100644
index 00000000000..3831d1a6bd4
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/http-req-resp-sizes-stats.yaml
@@ -0,0 +1,21 @@
+name: "metrics-req-resp-sizes-stats"
+metrics:
+ enableRequestResponseSizesStats: true
+http:
+ - name: "listener-enable-req-resp-sizes-stats"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-direct-response.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-direct-response.yaml
index 9db15c7fb9d..c51cf53a389 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-direct-response.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-direct-response.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-dns-cluster.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-dns-cluster.yaml
index 1cb0be3ec26..12986c3ed86 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-dns-cluster.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-dns-cluster.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-mirror.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-mirror.yaml
index b00449b384f..5d000b85bdf 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-mirror.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-mirror.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-multiple-mirrors.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-multiple-mirrors.yaml
index 3d13de381be..02724f765d7 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-multiple-mirrors.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-multiple-mirrors.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-partial-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-partial-invalid.yaml
index d72ec1d2c68..ad06367ef75 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-partial-invalid.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-partial-invalid.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-redirect.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-redirect.yaml
index 1c541a9caac..dd2a5aaeb1c 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-redirect.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-redirect.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-regex.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-regex.yaml
index d9558ad99a2..cfa271c3e98 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-regex.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-regex.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-request-headers.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-request-headers.yaml
index c3dc4417dcc..7bd5a5013cf 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-request-headers.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-request-headers.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -18,20 +18,30 @@ http:
- host: "1.2.3.4"
port: 50000
addRequestHeaders:
+ - name: "some-header-multi-value"
+ value:
+ - "some-value"
+ - "some-additional-value"
+ append: true
- name: "some-header"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header-2"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header3"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "some-header4"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "empty-header"
- value: ""
+ value:
+ - ""
append: false
removeRequestHeaders:
- "some-header5"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-headers.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-headers.yaml
index e3114e2d252..c27f02da065 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-headers.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-headers.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -19,17 +19,22 @@ http:
port: 50000
addResponseHeaders:
- name: "some-header"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header-2"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header3"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "some-header4"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "empty-header"
- value: ""
+ value:
+ - ""
append: false
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-remove-headers.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-remove-headers.yaml
index 0e59f8f124d..d04cc086e90 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-remove-headers.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-remove-headers.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -19,19 +19,24 @@ http:
port: 50000
addResponseHeaders:
- name: "some-header"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header-2"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header3"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "some-header4"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "empty-header"
- value: ""
+ value:
+ - ""
append: false
removeResponseHeaders:
- "some-header5"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-response-remove-headers.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-response-remove-headers.yaml
index f7b30b3d7d6..8ecd2bb4c74 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-response-remove-headers.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-response-remove-headers.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-root-path-url-prefix.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-root-path-url-prefix.yaml
index f4307644514..97e92bd1f25 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-root-path-url-prefix.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-root-path-url-prefix.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.yaml
new file mode 100644
index 00000000000..3dce5f3d6a9
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.yaml
@@ -0,0 +1,27 @@
+name: "http-route"
+http:
+- name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "rewrite-route"
+ pathMatch:
+ prefix: "/origin/"
+ hostname: gateway.envoyproxy.io
+ headerMatches:
+ - name: ":authority"
+ exact: gateway.envoyproxy.io
+ destination:
+ name: "rewrite-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ urlRewrite:
+ path:
+ prefixMatchReplace: /rewrite/
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-fullpath.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-fullpath.yaml
index 4d08acb93ee..a3c9eef83cf 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-fullpath.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-fullpath.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-host.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-host.yaml
index 8cc673a7e5b..7e971a596c6 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-host.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-host.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -23,6 +23,43 @@ http:
- host: "1.2.3.4"
port: 50000
urlRewrite:
- hostname: "3.3.3.3"
+ host:
+ name: "3.3.3.3"
+ path:
+ prefixMatchReplace: /rewrite
+ - name: "rewrite-host-header"
+ pathMatch:
+ prefix: "/host-header"
+ hostname: gateway.envoyproxy.io
+ headerMatches:
+ - name: ":authority"
+ exact: gateway.envoyproxy.io
+ destination:
+ name: "rewrite-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ urlRewrite:
+ host:
+ header: "foo"
+ path:
+ prefixMatchReplace: /rewrite
+ - name: "rewrite-host-backend"
+ pathMatch:
+ prefix: "/host-backend"
+ hostname: gateway.envoyproxy.io
+ headerMatches:
+ - name: ":authority"
+ exact: gateway.envoyproxy.io
+ destination:
+ name: "rewrite-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ urlRewrite:
+ host:
+ backend: true
path:
prefixMatchReplace: /rewrite
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-prefix.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-prefix.yaml
index df4f2e9c2bf..de751b8680b 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-prefix.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-prefix.yaml
@@ -1,7 +1,7 @@
name: "http-route"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-regex.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-regex.yaml
new file mode 100644
index 00000000000..531ac4a2941
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-rewrite-url-regex.yaml
@@ -0,0 +1,26 @@
+name: "http-route"
+http:
+- name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "rewrite-route"
+ pathMatch:
+ prefix: "/origin"
+ hostname: gateway.envoyproxy.io
+ destination:
+ name: "rewrite-route"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ urlRewrite:
+ path:
+ regexMatchReplace:
+ pattern: '^/service/([^/]+)(/.*)$'
+ substitution: '\2/instance/\1'
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-session-persistence.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-session-persistence.yaml
new file mode 100644
index 00000000000..d5cfffa0e4b
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-session-persistence.yaml
@@ -0,0 +1,66 @@
+http:
+- name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "header-based-session-persistence-route"
+ hostname: "*"
+ pathMatch:
+ safeRegex: "/v1/.*"
+ sessionPersistence:
+ header: {
+ name: "session-header"
+ }
+ destination:
+ name: "regex-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "cookie-based-session-persistence-route-regex"
+ hostname: "*"
+ pathMatch:
+ safeRegex: "/v1/.*/hoge"
+ sessionPersistence:
+ cookie:
+ name: "session-header"
+ ttl: "1h"
+ destination:
+ name: "regex-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "cookie-based-session-persistence-route-prefix"
+ hostname: "*"
+ pathMatch:
+ prefix: "/v2/"
+ sessionPersistence:
+ cookie:
+ name: "session-header"
+ ttl: "1h"
+ destination:
+ name: "regex-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "cookie-based-session-persistence-route-exact"
+ hostname: "*"
+ pathMatch:
+ exact: "/v3/user"
+ sessionPersistence:
+ cookie:
+ name: "session-cookie"
+ ttl: "1h"
+ destination:
+ name: "regex-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml
index 746d4922542..f14367f482e 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -48,3 +48,47 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50002
+ - name: "forth-route"
+ hostname: "*"
+ timeout: 10s
+ traffic:
+ timeout:
+ http:
+ requestTimeout: 5s
+ destination:
+ name: "fourth-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50002
+ - name: "fifth-route"
+ hostname: "*"
+ timeout: 10s
+ destination:
+ name: "fifth-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50002
+ - name: "sixth-route"
+ hostname: "*"
+ timeout: 0s
+ destination:
+ name: "sixth-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50002
+ - name: "seventh-route"
+ hostname: "*"
+ timeout: 0s
+ traffic:
+ timeout:
+ http:
+ requestTimeout: 5s
+ destination:
+ name: "seventh-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50002
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-uds-ip.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-uds-ip.yaml
index 711913d4dfd..90bf39f5ad0 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-uds-ip.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-uds-ip.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-with-filters.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-with-filters.yaml
index f8943d07f01..5789434790e 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-with-filters.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-with-filters.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
hostnames:
- '*'
path:
@@ -19,7 +19,8 @@ http:
addRequestHeaders:
- append: false
name: add-header-3
- value: some-value
+ value:
+ - some-value
protocol: HTTP
weight: 1
hostname: '*'
@@ -37,10 +38,12 @@ http:
addRequestHeaders:
- append: true
name: add-header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-2
- value: some-value
+ value:
+ - some-value
protocol: HTTP
weight: 8
- addressType: IP
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend.yaml
index 2540dec625a..3a3df9cd596 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-invalid-backend.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-invalid-backend.yaml
index d883bac1fa1..c342dc30383 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-invalid-backend.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-invalid-backend.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route.yaml
index 0c89d5a1840..dff106a6ff1 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http1-preserve-case.yaml b/internal/xds/translator/testdata/in/xds-ir/http1-preserve-case.yaml
index f857ac8f854..1b6382fc71a 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http1-preserve-case.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http1-preserve-case.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -19,7 +19,7 @@ http:
- host: "1.2.3.4"
port: 50000
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10081
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http1-trailers.yaml b/internal/xds/translator/testdata/in/xds-ir/http1-trailers.yaml
index 51174744979..83fa599cfd0 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http1-trailers.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http1-trailers.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http10.yaml b/internal/xds/translator/testdata/in/xds-ir/http10.yaml
index 47f57a04422..fea6bafa0e5 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http10.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http10.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "foo.com"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml b/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml
index f3dc12c5aae..1f11535ee18 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -28,3 +28,59 @@ http:
- host: "1.2.3.4"
port: 50000
protocol: GRPC
+ traffic:
+ http2:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 524288000
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ - name: "second-route"
+ hostname: "*"
+ pathMatch:
+ name: "test"
+ exact: "bar/foo"
+ destination:
+ name: "second-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ protocol: GRPC
+ traffic:
+ http2: {}
+ - name: "third-route-use-client"
+ hostname: "*"
+ pathMatch:
+ name: "test"
+ exact: "bar/bar"
+ destination:
+ name: "third-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ protocol: HTTP
+ useClientProtocol: true
+ traffic:
+ http2:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 524288000
+ maxConcurrentStreams: 200
+ resetStreamOnError: false
+ - name: "fourth-route-not-http2"
+ hostname: "*"
+ pathMatch:
+ name: "test"
+ exact: "foo/foo"
+ destination:
+ name: "fourth-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ traffic:
+ http2:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 524288000
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
diff --git a/internal/xds/translator/testdata/in/xds-ir/http2.yaml b/internal/xds/translator/testdata/in/xds-ir/http2.yaml
index c95bc0442c0..ffa5e487a7a 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http2.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http2.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "foo.com"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-empty-jsonpath.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-empty-jsonpath.yaml
new file mode 100644
index 00000000000..8d78880b81b
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-empty-jsonpath.yaml
@@ -0,0 +1,63 @@
+envoyPatchPolicies:
+- status:
+ ancestors:
+ - ancestorRef:
+ group: "gateway.networking.k8s.io"
+ kind: "Gateway"
+ namespace: "default"
+ name: "foobar"
+ name: "first-policy"
+ namespace: "default"
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: second-listener
+ operation:
+ op: add
+ value:
+ clusterName: second-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 4.5.6.7
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
+http:
+- name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ tls:
+ alpnProtocols:
+ - h2
+ - http/1.1
+ certificates:
+ - name: secret-1
+ # byte slice representation of "key-data"
+ serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ # byte slice representation of "key-data"
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ - name: secret-2
+ serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ headerMatches:
+ - name: user
+ stringMatch:
+ exact: "jason"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-without-value.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-without-value.yaml
index b4659755214..2dea53dcc3c 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-without-value.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-without-value.yaml
@@ -33,7 +33,7 @@ envoyPatchPolicies:
path: "/virtual_hosts/0/rate_limits"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-invalid-patch.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-invalid-patch.yaml
index 551bdd6dda6..70ae0f10710 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-invalid-patch.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-invalid-patch.yaml
@@ -28,7 +28,7 @@ envoyPatchPolicies:
transport_api_version: V3
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-missing-resource.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-missing-resource.yaml
index 3f50ddf7aaf..f10bf20addc 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-missing-resource.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-missing-resource.yaml
@@ -28,7 +28,7 @@ envoyPatchPolicies:
transport_api_version: V3
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-move-op-with-value.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-move-op-with-value.yaml
index d66eaa633db..dd586aec3ea 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-move-op-with-value.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-move-op-with-value.yaml
@@ -36,7 +36,7 @@ envoyPatchPolicies:
test: "abc"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-with-jsonpath-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-with-jsonpath-invalid.yaml
new file mode 100644
index 00000000000..9b0d7b4937b
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-with-jsonpath-invalid.yaml
@@ -0,0 +1,68 @@
+envoyPatchPolicies:
+- status:
+ ancestors:
+ - ancestorRef:
+ group: "gateway.networking.k8s.io"
+ kind: "Gateway"
+ namespace: "default"
+ name: "foobar"
+ name: "first-policy"
+ namespace: "default"
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: "first-route-dest"
+ operation:
+ op: "replace"
+ jsonPath: "..doesNotExists"
+ value: "50"
+http:
+- name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ tls:
+ alpnProtocols:
+ - h2
+ - http/1.1
+ certificates:
+ - name: secret-1
+ # byte slice representation of "key-data"
+ serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ # byte slice representation of "key-data"
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ - name: secret-2
+ serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ headerMatches:
+ - name: user
+ stringMatch:
+ exact: "jason"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "second-route"
+ hostname: "*"
+ headerMatches:
+ - name: user
+ stringMatch:
+ exact: "james"
+ - name: country
+ stringMatch:
+ exact: "US"
+ destination:
+ name: "second-route-dest"
+ settings:
+ - endpoints:
+ - host: "4.5.6.7"
+ port: 60000
+
diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-with-jsonpath.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-with-jsonpath.yaml
new file mode 100644
index 00000000000..34ca0aff98c
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-with-jsonpath.yaml
@@ -0,0 +1,172 @@
+envoyPatchPolicies:
+- status:
+ ancestors:
+ - ancestorRef:
+ group: "gateway.networking.k8s.io"
+ kind: "Gateway"
+ namespace: "default"
+ name: "foobar"
+ name: "first-policy"
+ namespace: "default"
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.listener.v3.Listener"
+ name: first-listener
+ operation:
+ op: "add"
+ jsonPath: "$.filter_chains[0].filters[0].typed_config"
+ path: "/preserve_external_request_id"
+ value: true
+ - type: "type.googleapis.com/envoy.config.listener.v3.Listener"
+ name: "first-listener"
+ operation:
+ op: "add"
+ jsonPath: "filter_chains[0].filters[0].typed_config.http_filters[0]"
+ value:
+ name: "envoy.filters.http.ratelimit"
+ typed_config:
+ "@type": "type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit"
+ domain: "eg-ratelimit"
+ failure_mode_deny: true
+ timeout: 1s
+ rate_limit_service:
+ grpc_service:
+ envoy_grpc:
+ cluster_name: rate-limit-cluster
+ transport_api_version: V3
+ - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
+ name: "first-listener"
+ operation:
+ op: "add"
+ jsonPath: "virtual_hosts[0]"
+ path: "rate_limits"
+ value:
+ - actions:
+ - remote_address: {}
+ - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
+ name: "first-listener"
+ operation:
+ op: "replace"
+ jsonPath: "..routes[?(@.name=='second-route')].route.upgrade_configs"
+ value:
+ - upgrade_type: CONNECT
+ connect_config:
+ {}
+ - type: "type.googleapis.com/envoy.config.cluster.v3.Cluster"
+ name: rate-limit-cluster
+ operation:
+ op: add
+ path: ""
+ value:
+ name: rate-limit-cluster
+ type: STRICT_DNS
+ connect_timeout: 10s
+ lb_policy: ROUND_ROBIN
+ http2_protocol_options: {}
+ load_assignment:
+ cluster_name: rate-limit-cluster
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: ratelimit.svc.cluster.local
+ port_value: 8081
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: "first-route-dest"
+ operation:
+ op: "replace"
+ jsonPath: "..endpoints[*].load_balancing_weight"
+ value: "50"
+ - type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
+ name: "secret-1"
+ operation:
+ op: "replace"
+ jsonPath: "$.tls_certificate.certificate_chain.inline_bytes"
+ value: "a2V5LWRhdGE="
+ - type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
+ name: "test-secret"
+ operation:
+ op: "add"
+ path: ""
+ value:
+ name: test_secret
+ tls_certificate:
+ certificate_chain:
+ inline_bytes: Y2VydC1kYXRh
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: "first-route-dest"
+ operation:
+ op: add
+ jsonPath: "endpoints"
+ path: "/1"
+ value:
+ lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: "first-route-dest"
+ operation:
+ op: "move"
+ from: "/endpoints/0/load_balancing_weight"
+ path: "/endpoints/1/load_balancing_weight"
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: "first-route-dest"
+ operation:
+ op: copy
+ from: "/endpoints/1/load_balancing_weight"
+ path: "/endpoints/0/load_balancing_weight"
+http:
+- name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ tls:
+ alpnProtocols:
+ - h2
+ - http/1.1
+ certificates:
+ - name: secret-1
+ # byte slice representation of "key-data"
+ serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ # byte slice representation of "key-data"
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ - name: secret-2
+ serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ headerMatches:
+ - name: user
+ stringMatch:
+ exact: "jason"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "second-route"
+ hostname: "*"
+ headerMatches:
+ - name: user
+ stringMatch:
+ exact: "james"
+ - name: country
+ stringMatch:
+ exact: "US"
+ destination:
+ name: "second-route-dest"
+ settings:
+ - endpoints:
+ - host: "4.5.6.7"
+ port: 60000
+
diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch.yaml
index 1aa76efdfab..04b88fca088 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jsonpatch.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch.yaml
@@ -109,7 +109,7 @@ envoyPatchPolicies:
path: "/endpoints/0/load_balancing_weight"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml
index 8d24373fd6a..1f0ff2189ec 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml
index 88f88f5aa35..3d52645831e 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml
index 324f54d9311..1e0a31975d4 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml
@@ -3,7 +3,7 @@ accesslog:
- path: "/dev/stdout"
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-optional.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-optional.yaml
index b43dd005257..7ab85e6928e 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jwt-optional.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jwt-optional.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml
index 008b5b9bde6..18957afe903 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml
index a5b72e0ff53..4df3cf34798 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/listener-connection-limit.yaml b/internal/xds/translator/testdata/in/xds-ir/listener-connection-limit.yaml
index 049ec905b9a..b758db9918b 100644
--- a/internal/xds/translator/testdata/in/xds-ir/listener-connection-limit.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/listener-connection-limit.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "foo.com"
@@ -18,7 +18,7 @@ http:
- host: "1.2.3.4"
port: 50000
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10081
hostnames:
- "foo.net"
@@ -39,31 +39,33 @@ http:
port: 50000
tcp:
- name: "third-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10082
connection:
limit:
value: 3
- tls:
- passthrough:
- snis:
- - bar.com
- destination:
- name: "tls-route-dest"
- settings:
- - endpoints:
- - host: "1.2.3.4"
- port: 50000
+ routes:
+ - tls:
+ inspector:
+ snis:
+ - bar.com
+ destination:
+ name: "tls-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
- name: "fourth-listener"
- address: "0.0.0.0"
+ address: "::"
connection:
limit:
value: 10
closeDelay: 3s
port: 10083
- destination:
- name: "tcp-route-dest"
- settings:
- - endpoints:
- - host: "1.2.3.4"
- port: 50000
+ routes:
+ - destination:
+ name: "tcp-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol.yaml b/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol.yaml
index 35f4e744093..f9f26a8103a 100644
--- a/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "foo.com"
@@ -32,7 +32,7 @@ http:
port: 50000
tcp:
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10081
enableProxyProtocol: true
routes:
diff --git a/internal/xds/translator/testdata/in/xds-ir/listener-tcp-keepalive.yaml b/internal/xds/translator/testdata/in/xds-ir/listener-tcp-keepalive.yaml
index 9bdaf244912..e9da0aa245f 100644
--- a/internal/xds/translator/testdata/in/xds-ir/listener-tcp-keepalive.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/listener-tcp-keepalive.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "foo.com"
@@ -18,7 +18,7 @@ http:
- host: "1.2.3.4"
port: 50000
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10081
hostnames:
- "foo.net"
@@ -40,27 +40,29 @@ http:
port: 50000
tcp:
- name: "third-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10082
tcpKeepalive: {}
- tls:
- inspector:
- snis:
- - bar.com
- destination:
- name: "tls-route-dest"
- settings:
- - endpoints:
- - host: "1.2.3.4"
- port: 50000
+ routes:
+ - tls:
+ inspector:
+ snis:
+ - bar.com
+ destination:
+ name: "tls-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
- name: "fourth-listener"
- address: "0.0.0.0"
+ address: "::"
tcpKeepalive:
probes: 10
port: 10083
- destination:
- name: "tcp-route-dest"
- settings:
- - endpoints:
- - host: "1.2.3.4"
- port: 50000
+ routes:
+ - destination:
+ name: "tcp-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/listener-tcp-without-route.yaml b/internal/xds/translator/testdata/in/xds-ir/listener-tcp-without-route.yaml
new file mode 100644
index 00000000000..cc24bfbdf00
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/listener-tcp-without-route.yaml
@@ -0,0 +1,17 @@
+tcp:
+- address: 0.0.0.0
+ connection:
+ bufferLimit: 50000000
+ limit:
+ closeDelay: 10s
+ value: 3
+ enableProxyProtocol: true
+ name: envoy-gateway/gateway-1/tls-1
+ port: 10443
+ tcpKeepalive:
+ idleTime: 1200
+ interval: 60
+ probes: 3
+ timeout:
+ tcp:
+ idleTimeout: 20m0s
diff --git a/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml b/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml
index d2b754bf16b..17a09c845b5 100644
--- a/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml
index fb7baf05cd6..8299d0f0823 100644
--- a/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/metrics-virtual-host.yaml b/internal/xds/translator/testdata/in/xds-ir/metrics-virtual-host.yaml
index 39f1a23dc7f..e326e5667cf 100644
--- a/internal/xds/translator/testdata/in/xds-ir/metrics-virtual-host.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/metrics-virtual-host.yaml
@@ -3,7 +3,7 @@ metrics:
enableVirtualHostStats: true
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/mixed-tls-jwt-authn.yaml b/internal/xds/translator/testdata/in/xds-ir/mixed-tls-jwt-authn.yaml
index e77e1262245..e1d7f0658fb 100644
--- a/internal/xds/translator/testdata/in/xds-ir/mixed-tls-jwt-authn.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/mixed-tls-jwt-authn.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port.yaml b/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port.yaml
index b694ac5aab0..3aca8e48b0b 100644
--- a/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "foo.com"
@@ -27,7 +27,7 @@ http:
- host: "1.2.3.4"
port: 50000
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "foo.net"
@@ -54,7 +54,7 @@ http:
- host: "1.2.3.4"
port: 50000
- name: "third-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "example.com"
@@ -71,7 +71,7 @@ http:
- host: "1.2.3.4"
port: 50000
- name: "fourth-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "example.net"
@@ -89,7 +89,7 @@ http:
port: 50000
tcp:
- name: "fifth-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "fifth-route"
@@ -104,7 +104,7 @@ tcp:
- host: "1.2.3.4"
port: 50000
- name: "sixth-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "sixth-route"
diff --git a/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml b/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml
index 19ad6357e9a..ba1eff21400 100644
--- a/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml
@@ -1,6 +1,6 @@
tcp:
- name: "tcp-listener-simple"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tcp-route-simple"
@@ -13,7 +13,7 @@ tcp:
- host: "5.6.7.8"
port: 50001
- name: "tcp-listener-simple-1"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tcp-route-simple-1"
@@ -26,7 +26,7 @@ tcp:
- host: "5.6.7.8"
port: 50001
- name: "tcp-listener-simple-2"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tcp-route-simple-2"
@@ -39,7 +39,7 @@ tcp:
- host: "5.6.7.8"
port: 50001
- name: "tcp-listener-simple-3"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tcp-route-simple-3"
@@ -52,7 +52,7 @@ tcp:
- host: "5.6.7.8"
port: 50001
- name: "tcp-listener-simple-4"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tcp-route-simple-4"
diff --git a/internal/xds/translator/testdata/in/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.yaml b/internal/xds/translator/testdata/in/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.yaml
index aac60cf7c41..b975466c27a 100644
--- a/internal/xds/translator/testdata/in/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10001
hostnames:
- "*"
@@ -36,7 +36,7 @@ http:
- host: "10.0.0.1"
port: 10001
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10002
hostnames:
- "*"
@@ -73,7 +73,7 @@ http:
- host: "10.0.0.1"
port: 10002
- name: "third-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10003
hostnames:
- "*"
@@ -111,7 +111,7 @@ http:
- host: "10.0.0.1"
port: 10003
- name: "fourth-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10004
hostnames:
- "*"
@@ -151,7 +151,7 @@ http:
- host: "10.0.0.1"
port: 10004
- name: "fifth-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10005
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/mutual-tls-forward-client-certificate.yaml b/internal/xds/translator/testdata/in/xds-ir/mutual-tls-forward-client-certificate.yaml
index 72eaea1f58e..5f50492e526 100644
--- a/internal/xds/translator/testdata/in/xds-ir/mutual-tls-forward-client-certificate.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/mutual-tls-forward-client-certificate.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10001
hostnames:
- "*"
@@ -36,7 +36,7 @@ http:
- host: "10.0.0.1"
port: 10001
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10002
hostnames:
- "*"
@@ -72,7 +72,7 @@ http:
- host: "10.0.0.1"
port: 10002
- name: "third-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10003
hostnames:
- "*"
@@ -108,7 +108,7 @@ http:
- host: "10.0.0.1"
port: 10003
- name: "fourth-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10004
hostnames:
- "*"
@@ -144,7 +144,7 @@ http:
- host: "10.0.0.1"
port: 10004
- name: "fifth-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10005
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/mutual-tls-required-client-certificate-disabled.yaml b/internal/xds/translator/testdata/in/xds-ir/mutual-tls-required-client-certificate-disabled.yaml
index 67b17e8158b..cfe94ba32f3 100644
--- a/internal/xds/translator/testdata/in/xds-ir/mutual-tls-required-client-certificate-disabled.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/mutual-tls-required-client-certificate-disabled.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -35,7 +35,7 @@ http:
port: 50000
tcp:
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10081
tls:
certificates:
@@ -52,6 +52,7 @@ tcp:
- name: "tls-route-terminate"
tls:
terminate:
+ alpnProtocols: []
certificates:
- name: secret-3
# byte slice representation of "key-data"
diff --git a/internal/xds/translator/testdata/in/xds-ir/mutual-tls.yaml b/internal/xds/translator/testdata/in/xds-ir/mutual-tls.yaml
index ff96a528eaa..d4ba0f617e9 100644
--- a/internal/xds/translator/testdata/in/xds-ir/mutual-tls.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/mutual-tls.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -35,7 +35,7 @@ http:
port: 50000
tcp:
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10081
tls:
certificates:
@@ -52,6 +52,7 @@ tcp:
- name: "tls-route-terminate"
tls:
terminate:
+ alpnProtocols: []
certificates:
- name: secret-3
# byte slice representation of "key-data"
diff --git a/internal/xds/translator/testdata/in/xds-ir/oidc-backend-cluster-provider.yaml b/internal/xds/translator/testdata/in/xds-ir/oidc-backend-cluster-provider.yaml
new file mode 100644
index 00000000000..993f775947a
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/oidc-backend-cluster-provider.yaml
@@ -0,0 +1,60 @@
+http:
+- name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ pathMatch:
+ exact: "baz"
+ destination:
+ name: "third-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ security:
+ oidc:
+ name: securitypolicy/envoy-gateway/policy-for-gateway
+ clientID: client1.apps.googleusercontent.com
+ clientSecret: Y2xpZW50MTpzZWNyZXQK
+ cookieSuffix: b0a1b740
+ defaultRefreshTokenTTL: 24h0m0s
+ defaultTokenTTL: 30m0s
+ forwardAccessToken: true
+ hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY=
+ logoutPath: /bar/logout
+ provider:
+ authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth
+ destination:
+ name: securitypolicy/envoy-gateway/policy-for-gateway/0
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: oauth.foo.com
+ port: 443
+ protocol: HTTPS
+ weight: 1
+ tokenEndpoint: https://oauth.foo.com/token
+ traffic:
+ retry:
+ numRetries: 3
+ perRetry:
+ backOff:
+ baseInterval: 1s
+ maxInterval: 5s
+ retryOn:
+ triggers:
+ - "5xx"
+ - gateway-error
+ - reset
+ redirectPath: /bar/oauth2/callback
+ redirectURL: https://www.example.com/bar/oauth2/callback
+ refreshToken: true
+ scopes:
+ - openid
diff --git a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml
index 4775fa9676d..c2e75b916d0 100644
--- a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -73,3 +73,4 @@ http:
cookieNameOverrides:
idToken: "CustomIdTokenOverride"
accessToken: "CustomAccessTokenOverride"
+ cookieDomain: "example.com"
diff --git a/internal/xds/translator/testdata/in/xds-ir/path-settings.yaml b/internal/xds/translator/testdata/in/xds-ir/path-settings.yaml
index 1eddbaab253..e3752799fc6 100644
--- a/internal/xds/translator/testdata/in/xds-ir/path-settings.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/path-settings.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml b/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml
index 47df0026b9f..c1e4c9dd632 100644
--- a/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml
index 271d39cfdcb..663dda6eb06 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-disable-headers.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-disable-headers.yaml
index 7c48e227ecc..56028c4162c 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-disable-headers.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-disable-headers.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml
index 32f95117283..d7e2dea2ac1 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml
@@ -2,7 +2,7 @@ metrics:
enablePerEndpointStats: true
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-headers-and-cidr.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-headers-and-cidr.yaml
new file mode 100644
index 00000000000..d6b6a9b3245
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-headers-and-cidr.yaml
@@ -0,0 +1,88 @@
+http:
+- name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ traffic:
+ rateLimit:
+ global:
+ rules:
+ - headerMatches:
+ - name: "x-user-id"
+ exact: "one"
+ cidrMatch:
+ cidr: 192.168.0.0/16
+ maskLen: 16
+ limit:
+ requests: 5
+ unit: second
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "second-route"
+ hostname: "*"
+ traffic:
+ rateLimit:
+ global:
+ rules:
+ - headerMatches:
+ - name: "x-user-id"
+ distinct: true
+ - name: "foobar"
+ distinct: true
+ cidrMatch:
+ cidr: 192.168.0.0/16
+ maskLen: 16
+ limit:
+ requests: 5
+ unit: second
+ pathMatch:
+ exact: "example"
+ destination:
+ name: "second-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "third-route"
+ hostname: "*"
+ traffic:
+ rateLimit:
+ global:
+ rules:
+ - headerMatches:
+ - name: "x-user-id"
+ exact: "one"
+ cidrMatch:
+ cidr: 192.168.0.0/16
+ maskLen: 16
+ limit:
+ requests: 5
+ unit: second
+ - headerMatches:
+ - name: "x-user-id"
+ exact: "two"
+ - name: "foobar"
+ distinct: true
+ cidrMatch:
+ cidr: 192.169.0.0/16
+ maskLen: 16
+ limit:
+ requests: 10
+ unit: second
+ destination:
+ name: "third-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml
index 495fa9b7a1f..289104b1df3 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml
index 271d39cfdcb..7af166fca4d 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -65,3 +65,24 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
+ - name: "fourth-route"
+ hostname: "*"
+ traffic:
+ rateLimit:
+ global:
+ rules:
+ - headerMatches:
+ - name: "x-org-id"
+ exact: "admin"
+ invert: true
+ limit:
+ requests: 5
+ unit: second
+ pathMatch:
+ exact: "foo/bar/login"
+ destination:
+ name: "fourth-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml
index 7483356722d..cb883565f8c 100644
--- a/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/securitypolicy-with-oidc-jwt-authz.yaml b/internal/xds/translator/testdata/in/xds-ir/securitypolicy-with-oidc-jwt-authz.yaml
new file mode 100644
index 00000000000..fffcb7fd8bd
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/securitypolicy-with-oidc-jwt-authz.yaml
@@ -0,0 +1,80 @@
+http:
+- name: "envoy-gateway/gateway-1/http"
+ address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ security:
+ authorization:
+ defaultAction: Deny
+ rules:
+ - action: Allow
+ name: allow
+ principal:
+ jwt:
+ claims:
+ - name: groups
+ valueType: StringArray
+ values:
+ - foobar
+ provider: exjwt
+ jwt:
+ providers:
+ - claimToHeaders:
+ - claim: email
+ header: x-user-email
+ extractFrom:
+ cookies:
+ - IdToken
+ issuer: https://oidc.example.com/auth/realms/example
+ name: exjwt
+ remoteJWKS:
+ uri: https://oidc.example.com/auth/realms/example/protocol/openid-connect/certs
+ oidc:
+ clientID: prometheus
+ clientSecret: '[redacted]'
+ cookieNameOverrides:
+ idToken: IdToken
+ cookieSuffix: 5f93c2e4
+ hmacSecret: '[redacted]'
+ logoutPath: /logout
+ name: securitypolicy/default/policy-for-http-route
+ provider:
+ authorizationEndpoint: https://oidc.example.com/authorize
+ tokenEndpoint: https://oidc.example.com/oauth/token
+ redirectPath: /oauth2/callback
+ redirectURL: '%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback'
+ scopes:
+ - openid
+ - email
+ - profile
diff --git a/internal/xds/translator/testdata/in/xds-ir/simple-tls.yaml b/internal/xds/translator/testdata/in/xds-ir/simple-tls.yaml
index 7309020334a..fd1408fdf2d 100644
--- a/internal/xds/translator/testdata/in/xds-ir/simple-tls.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/simple-tls.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/suppress-envoy-headers.yaml b/internal/xds/translator/testdata/in/xds-ir/suppress-envoy-headers.yaml
index f26d13b084e..d01294ed199 100644
--- a/internal/xds/translator/testdata/in/xds-ir/suppress-envoy-headers.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/suppress-envoy-headers.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "foo.com"
diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-endpoint-stats.yaml
index 60176773c96..28ee60724bf 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tcp-endpoint-stats.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tcp-endpoint-stats.yaml
@@ -3,13 +3,14 @@ metrics:
enablePerEndpointStats: true
tcp:
- name: "tcp-route-enable-endpoint-stats"
- address: "0.0.0.0"
+ address: "::"
port: 10080
- destination:
- name: "tcp-route-simple-dest"
- settings:
- - endpoints:
- - host: "1.2.3.4"
- port: 50000
- - host: "5.6.7.8"
- port: 50001
+ routes:
+ - destination:
+ name: "tcp-route-simple-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - host: "5.6.7.8"
+ port: 50001
diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-listener-ipfamily.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-listener-ipfamily.yaml
new file mode 100644
index 00000000000..b74056ec017
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/tcp-listener-ipfamily.yaml
@@ -0,0 +1,13 @@
+tcp:
+ - name: tcp-listener-dual
+ address: 0.0.0.0
+ port: 8082
+ ipFamily: DualStack
+ routes:
+ - name: tcp-route-dual
+ destination:
+ name: tcp-route-dual-dest
+ settings:
+ - endpoints:
+ - host: 192.168.1.2
+ - host: '2001:db8::2'
diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-req-resp-sizes-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-req-resp-sizes-stats.yaml
new file mode 100644
index 00000000000..1b915c58433
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/tcp-req-resp-sizes-stats.yaml
@@ -0,0 +1,16 @@
+name: "metrics-req-resp-sizes-stats"
+metrics:
+ enableRequestResponseSizesStats: true
+tcp:
+- name: "tcp-route-enable-req-resp-sizes-stats"
+ address: "::"
+ port: 10080
+ routes:
+ - destination:
+ name: "tcp-route-simple-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - host: "5.6.7.8"
+ port: 50001
diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml
index 901c0f66f40..48f58cd84dc 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml
@@ -1,6 +1,6 @@
tcp:
- name: "tcp-listener-complex"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tcp-route-complex"
diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid-endpoint.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid-endpoint.yaml
index 427472d6832..80511b12899 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid-endpoint.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid-endpoint.yaml
@@ -1,6 +1,6 @@
tcp:
- name: "tcp-listener-simple"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tcp-route-simple"
diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml
index 58f1ec03892..ae3ab3fc127 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml
@@ -1,6 +1,6 @@
tcp:
- name: "tcp-listener-simple"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tcp-route-simple"
diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-tls-terminate.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-tls-terminate.yaml
index 4e5be724781..86d0101d657 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-tls-terminate.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-tls-terminate.yaml
@@ -1,11 +1,12 @@
tcp:
- name: "tls-listener-terminate"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tls-route-terminate"
tls:
terminate:
+ alpnProtocols: []
certificates:
- Name: envoy-gateway-tls-secret-1
PrivateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
@@ -19,7 +20,7 @@ tcp:
- host: "5.6.7.8"
port: 50001
- name: "tls-terminate-hostname"
- address: "0.0.0.0"
+ address: "::"
port: 10080
tls:
inspector:
@@ -27,6 +28,7 @@ tcp:
- "*.envoyproxy.io"
- "example.com"
terminate:
+ alpnProtocols: []
certificates:
- Name: envoy-gateway-tls-secret-1
PrivateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml
index 73081048864..2e5e133bc25 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml
@@ -1,6 +1,6 @@
tcp:
- name: "tcp-listener-weighted-backend"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tcp-route-weighted-backend"
diff --git a/internal/xds/translator/testdata/in/xds-ir/timeout.yaml b/internal/xds/translator/testdata/in/xds-ir/timeout.yaml
index 8abc0af3cdd..f33270a0dd5 100644
--- a/internal/xds/translator/testdata/in/xds-ir/timeout.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/timeout.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/tls-route-passthrough.yaml b/internal/xds/translator/testdata/in/xds-ir/tls-route-passthrough.yaml
index 285927c9017..54da9ebef28 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tls-route-passthrough.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tls-route-passthrough.yaml
@@ -1,6 +1,6 @@
tcp:
- name: "tls-passthrough-foo"
- address: "0.0.0.0"
+ address: "::"
port: 10080
routes:
- name: "tls-route-passthrough-foo"
@@ -17,7 +17,7 @@ tcp:
- host: "5.6.7.8"
port: 50001
- name: "tls-passthrough-bar"
- address: "0.0.0.0"
+ address: "::"
port: 10081
routes:
- name: "tls-route-passthrough-bar"
diff --git a/internal/xds/translator/testdata/in/xds-ir/tls-with-ciphers-versions-alpn.yaml b/internal/xds/translator/testdata/in/xds-ir/tls-with-ciphers-versions-alpn.yaml
index 03e161599b7..6e70e3afba0 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tls-with-ciphers-versions-alpn.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tls-with-ciphers-versions-alpn.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
path:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
@@ -30,6 +30,7 @@ http:
minVersion: "1.0"
alpnProtocols:
- some-other-protocol
+ statefulSessionResumption: true
certificates:
- name: secret-1
# byte slice representation of "key-data"
@@ -50,7 +51,7 @@ http:
port: 50000
tcp:
- name: "second-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10081
tls:
ciphers:
@@ -107,6 +108,7 @@ tcp:
minVersion: "1.0"
alpnProtocols:
- some-other-protocol
+ statelessSessionResumption: true
certificates:
- name: secret-3
# byte slice representation of "key-data"
diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-datadog.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-datadog.yaml
new file mode 100644
index 00000000000..55c83e0bd0d
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/tracing-datadog.yaml
@@ -0,0 +1,46 @@
+name: "tracing"
+tracing:
+ serviceName: "fake-name.fake-ns"
+ samplingRate: 90
+ customTags:
+ "literal1":
+ type: Literal
+ literal:
+ value: "value1"
+ "env1":
+ type: Environment
+ environment:
+ name: "env1"
+ defaultValue: "-"
+ "req1":
+ type: RequestHeader
+ requestHeader:
+ name: "X-Request-Id"
+ defaultValue: "-"
+ authority: "datadog-agent.default.svc.cluster.local"
+ destination:
+ name: "tracing-0"
+ settings:
+ - endpoints:
+ - host: "datadog-agent.default.svc.cluster.local"
+ port: 8126
+ provider:
+ type: Datadog
+http:
+ - name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "direct-route"
+ hostname: "*"
+ destination:
+ name: "direct-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml
index b5ee8b57dd9..c5ddea6b9ab 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml
@@ -33,7 +33,7 @@ tracing:
type: OpenTelemetry
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -49,6 +49,3 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
- directResponse:
- body: "Unknown custom filter type: UnsupportedType"
- statusCode: 500
diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-invalid.yaml
index d8b23c5d21e..3a9a50904f6 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tracing-invalid.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tracing-invalid.yaml
@@ -22,7 +22,7 @@ tracing:
port: 4317
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-unknown-provider-type.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-unknown-provider-type.yaml
index 45f669ef643..dad1fdba41b 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tracing-unknown-provider-type.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tracing-unknown-provider-type.yaml
@@ -17,20 +17,20 @@ tracing:
requestHeader:
name: "X-Request-Id"
defaultValue: "-"
- authority: "datadog-agent.default.svc.cluster.local"
+ authority: "awesome-agent.default.svc.cluster.local"
destination:
name: "tracing-0"
settings:
- endpoints:
- - host: "datadog-agent.default.svc.cluster.local"
- port: 8126
+ - host: "awesome-agent.default.svc.cluster.local"
+ port: 1357
provider:
- host: datadog-agent.monitoring.svc.cluster.local
- port: 8126
- type: Datadog
+ host: awesome-agent.monitoring.svc.cluster.local
+ port: 1357
+ type: AwesomeTelemetry
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-zipkin.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-zipkin.yaml
index 9b4e57fd74f..52f559c907b 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tracing-zipkin.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tracing-zipkin.yaml
@@ -34,7 +34,7 @@ tracing:
disableSharedSpanContext: true
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -50,6 +50,3 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
- directResponse:
- body: "Unknown custom filter type: UnsupportedType"
- statusCode: 500
diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml
index 0f3555524ff..7762d44b525 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml
@@ -25,13 +25,34 @@ tracing:
- host: "otel-collector.default.svc.cluster.local"
port: 4317
protocol: "GRPC"
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ baseEjectionTime: 30s
+ consecutiveGatewayErrors: 4
+ consecutive5XxErrors: 5
+ consecutiveLocalOriginFailures: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ splitExternalLocalOriginErrors: false
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
provider:
host: otel-collector.monitoring.svc.cluster.local
port: 4317
type: OpenTelemetry
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
@@ -47,6 +68,3 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
- directResponse:
- body: "Unknown custom filter type: UnsupportedType"
- statusCode: 500
diff --git a/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml
index fc597f28928..9e27ffc95aa 100644
--- a/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml
@@ -3,7 +3,7 @@ metrics:
enablePerEndpointStats: true
udp:
- name: "udp-route-enable-endpoint-stats"
- address: "0.0.0.0"
+ address: "::"
port: 10080
route:
name: "udp-route"
diff --git a/internal/xds/translator/testdata/in/xds-ir/udp-req-resp-sizes-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/udp-req-resp-sizes-stats.yaml
new file mode 100644
index 00000000000..39f7cf99cf2
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/udp-req-resp-sizes-stats.yaml
@@ -0,0 +1,17 @@
+name: "metrics-req-resp-sizes-stats"
+metrics:
+ enableRequestResponseSizesStats: true
+udp:
+- name: "udp-route-enable-req-resp-sizes-stats"
+ address: "::"
+ port: 10080
+ route:
+ name: "udp-route"
+ destination:
+ name: "udp-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - host: "5.6.7.8"
+ port: 50001
diff --git a/internal/xds/translator/testdata/in/xds-ir/udp-route.yaml b/internal/xds/translator/testdata/in/xds-ir/udp-route.yaml
index a933bdd78a4..8f59089835b 100644
--- a/internal/xds/translator/testdata/in/xds-ir/udp-route.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/udp-route.yaml
@@ -1,6 +1,6 @@
udp:
- name: "udp-route"
- address: "0.0.0.0"
+ address: "::"
port: 10080
route:
name: "udp-route"
diff --git a/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml b/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml
index b00f5e55a3b..c66533226d8 100644
--- a/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml
@@ -1,6 +1,6 @@
http:
- name: "first-listener"
- address: "0.0.0.0"
+ address: "::"
port: 10080
hostnames:
- "*"
diff --git a/internal/xds/translator/testdata/in/xds-ir/wasm.yaml b/internal/xds/translator/testdata/in/xds-ir/wasm.yaml
index 9afa2c97c9c..756e38952fa 100644
--- a/internal/xds/translator/testdata/in/xds-ir/wasm.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/wasm.yaml
@@ -89,3 +89,6 @@ http:
sha256: 2a19e4f337e5223d7287e7fccd933fb01905deaff804292e5257f8c681b82bee
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2
wasmName: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2
+ hostKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
diff --git a/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.clusters.yaml b/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.clusters.yaml
index 8012c6fa499..4e46c1dfc61 100644
--- a/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.clusters.yaml
+++ b/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.clusters.yaml
@@ -4,15 +4,49 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: http-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: http-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: tcp-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: tcp-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: udp-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: udp-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- loadAssignment:
diff --git a/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.endpoints.yaml b/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.endpoints.yaml
index 8869685de5e..9308c055cfe 100644
--- a/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.endpoints.yaml
+++ b/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.endpoints.yaml
@@ -1,3 +1,27 @@
+- clusterName: http-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: http-route-dest/backend/0
+- clusterName: tcp-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: tcp-route-dest/backend/0
- clusterName: udp-route-dest
endpoints:
- lbEndpoints:
diff --git a/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.listeners.yaml b/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.listeners.yaml
index 3d5d41d69ff..6fbaf5053ec 100644
--- a/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.listeners.yaml
+++ b/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.listeners.yaml
@@ -27,10 +27,16 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-1/http1
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway/gateway-1/http1
- drainType: MODIFY_ONLY
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.tcp_proxy
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+ cluster: tcp-route-dest
+ statPrefix: tcp-10080
name: envoy-gateway/gateway-1/http1
perConnectionBufferLimitBytes: 32768
statPrefix: envoy-gateway/gateway-1/http1
diff --git a/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.routes.yaml b/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.routes.yaml
index b03ec37faa6..bfcb22e483f 100644
--- a/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.routes.yaml
+++ b/internal/xds/translator/testdata/out/extension-xds-ir/extensionpolicy-tcp-udp-http.routes.yaml
@@ -1,2 +1,14 @@
- ignorePortInHostMatching: true
name: envoy-gateway/gateway-1/http1
+ virtualHosts:
+ - domains:
+ - '*'
+ name: envoy-gateway/gateway-1/http1/*
+ routes:
+ - match:
+ prefix: /
+ name: http-route
+ route:
+ cluster: http-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/extension-xds-ir/http-route-extension-filter.clusters.yaml b/internal/xds/translator/testdata/out/extension-xds-ir/http-route-extension-filter.clusters.yaml
index 45f45f5c9bf..0dcc3b48190 100644
--- a/internal/xds/translator/testdata/out/extension-xds-ir/http-route-extension-filter.clusters.yaml
+++ b/internal/xds/translator/testdata/out/extension-xds-ir/http-route-extension-filter.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- loadAssignment:
diff --git a/internal/xds/translator/testdata/out/extension-xds-ir/http-route-extension-filter.listeners.yaml b/internal/xds/translator/testdata/out/extension-xds-ir/http-route-extension-filter.listeners.yaml
index 2f7f43464c0..e6777ebece3 100644
--- a/internal/xds/translator/testdata/out/extension-xds-ir/http-route-extension-filter.listeners.yaml
+++ b/internal/xds/translator/testdata/out/extension-xds-ir/http-route-extension-filter.listeners.yaml
@@ -27,10 +27,9 @@
resourceApiVersion: V3
routeConfigName: extension-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: extension-listener
- drainType: MODIFY_ONLY
name: extension-listener
perConnectionBufferLimitBytes: 32768
statPrefix: mock-extension-inserted-prefix
diff --git a/internal/xds/translator/testdata/out/extension-xds-ir/http-route.clusters.yaml b/internal/xds/translator/testdata/out/extension-xds-ir/http-route.clusters.yaml
index 45f45f5c9bf..0dcc3b48190 100644
--- a/internal/xds/translator/testdata/out/extension-xds-ir/http-route.clusters.yaml
+++ b/internal/xds/translator/testdata/out/extension-xds-ir/http-route.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- loadAssignment:
diff --git a/internal/xds/translator/testdata/out/extension-xds-ir/http-route.listeners.yaml b/internal/xds/translator/testdata/out/extension-xds-ir/http-route.listeners.yaml
index 67922c7444f..c3fb113017a 100644
--- a/internal/xds/translator/testdata/out/extension-xds-ir/http-route.listeners.yaml
+++ b/internal/xds/translator/testdata/out/extension-xds-ir/http-route.listeners.yaml
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/extension-xds-ir/listener-policy.listeners.yaml b/internal/xds/translator/testdata/out/extension-xds-ir/listener-policy.listeners.yaml
index 759e1ffb857..7837e1509fc 100644
--- a/internal/xds/translator/testdata/out/extension-xds-ir/listener-policy.listeners.yaml
+++ b/internal/xds/translator/testdata/out/extension-xds-ir/listener-policy.listeners.yaml
@@ -27,10 +27,9 @@
resourceApiVersion: V3
routeConfigName: policyextension-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10081
useRemoteAddress: true
name: policyextension-listener
- drainType: MODIFY_ONLY
name: policyextension-listener
perConnectionBufferLimitBytes: 32768
statPrefix: from-the-policy
diff --git a/internal/xds/translator/testdata/out/ratelimit-config/header-and-cidr-matches.yaml b/internal/xds/translator/testdata/out/ratelimit-config/header-and-cidr-matches.yaml
new file mode 100644
index 00000000000..83f5376dade
--- /dev/null
+++ b/internal/xds/translator/testdata/out/ratelimit-config/header-and-cidr-matches.yaml
@@ -0,0 +1,38 @@
+name: first-listener
+domain: first-listener
+descriptors:
+ - key: first-route
+ value: first-route
+ rate_limit: null
+ descriptors:
+ - key: rule-0-match-0
+ value: rule-0-match-0
+ rate_limit: null
+ descriptors:
+ - key: rule-0-match-1
+ value: rule-0-match-1
+ rate_limit: null
+ descriptors:
+ - key: rule-0-match-2
+ value: rule-0-match-2
+ rate_limit: null
+ descriptors:
+ - key: masked_remote_address
+ value: 0.0.0.0/0
+ rate_limit:
+ requests_per_unit: 5
+ unit: SECOND
+ unlimited: false
+ name: ""
+ replaces: []
+ descriptors: []
+ shadow_mode: false
+ detailed_metric: false
+ shadow_mode: false
+ detailed_metric: false
+ shadow_mode: false
+ detailed_metric: false
+ shadow_mode: false
+ detailed_metric: false
+ shadow_mode: false
+ detailed_metric: false
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml
index 18b309bb74d..86fb50d1d4e 100755
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml
@@ -1,22 +1,45 @@
- circuitBreakers:
thresholds:
- - maxRetries: 1024
+ - maxConnections: 2048
+ maxRetries: 1024
commonLbConfig:
localityWeightedLbConfig: {}
- connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ connectTimeout: 15s
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: accesslog/monitoring/envoy-als/port/9000
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: accesslog/monitoring/envoy-als/port/9000
- outlierDetection: {}
- perConnectionBufferLimitBytes: 32768
+ outlierDetection:
+ baseEjectionTime: 30s
+ consecutive5xx: 5
+ consecutiveGatewayFailure: 4
+ consecutiveLocalOriginFailure: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ perConnectionBufferLimitBytes: 20971520
+ transportSocket:
+ name: envoy.transport_sockets.upstream_proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport
+ config:
+ version: V2
+ transportSocket:
+ name: envoy.transport_sockets.raw_buffer
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ upstreamConnectionOptions:
+ tcpKeepalive:
+ keepaliveProbes: 7
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.clusters.yaml
index b8874bf24f9..81c121a400e 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: direct-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,7 +21,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -38,7 +38,6 @@
locality:
region: accesslog-0/backend/0
name: accesslog-0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
type: STRICT_DNS
@@ -46,4 +45,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.listeners.yaml
index 2ccfca8ce50..82af12d1330 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.listeners.yaml
@@ -82,7 +82,7 @@
stringValue: cluster1
address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -176,9 +176,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.routes.yaml
index b214e8b05a3..ea343799ac1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.routes.yaml
@@ -5,8 +5,10 @@
- '*'
name: first-listener/*
routes:
- - directResponse:
- status: 500
- match:
+ - match:
prefix: /
name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml
index cbf453a1f17..37bb1cef24f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: direct-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
trackClusterStats:
perEndpointStats: true
@@ -23,7 +23,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -40,7 +40,6 @@
locality:
region: accesslog-0/backend/0
name: accesslog-0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
trackClusterStats:
@@ -50,4 +49,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml
index 8e582b05b7e..ac530c829eb 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml
@@ -61,7 +61,7 @@
stringValue: cluster1
address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -137,9 +137,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.routes.yaml
index b214e8b05a3..ea343799ac1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.routes.yaml
@@ -5,8 +5,10 @@
- '*'
name: first-listener/*
routes:
- - directResponse:
- status: 500
- match:
+ - match:
prefix: /
name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml
index b8874bf24f9..81c121a400e 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: direct-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,7 +21,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -38,7 +38,6 @@
locality:
region: accesslog-0/backend/0
name: accesslog-0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
type: STRICT_DNS
@@ -46,4 +45,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.listeners.yaml
index 4bc751c2eca..6efcf6de185 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.listeners.yaml
@@ -105,7 +105,7 @@
stringValue: cluster1
address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -221,9 +221,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.routes.yaml
index b214e8b05a3..ea343799ac1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.routes.yaml
@@ -5,8 +5,10 @@
- '*'
name: first-listener/*
routes:
- - directResponse:
- status: 500
- match:
+ - match:
prefix: /
name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.clusters.yaml
index b8874bf24f9..81c121a400e 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: direct-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,7 +21,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -38,7 +38,6 @@
locality:
region: accesslog-0/backend/0
name: accesslog-0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
type: STRICT_DNS
@@ -46,4 +45,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.listeners.yaml
index 0bca441a443..f1efd677973 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.listeners.yaml
@@ -97,7 +97,7 @@
stringValue: cluster1
address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -212,9 +212,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.routes.yaml
index b214e8b05a3..ea343799ac1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.routes.yaml
@@ -5,8 +5,10 @@
- '*'
name: first-listener/*
routes:
- - directResponse:
- status: 500
- match:
+ - match:
prefix: /
name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-types.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-types.clusters.yaml
new file mode 100644
index 00000000000..088632d3506
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-types.clusters.yaml
@@ -0,0 +1,260 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: direct-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: accesslog_als_0_1
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: accesslog_als_0_1
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: accesslog_als_0_2
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: accesslog_als_0_2
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: accesslog_als_1_1
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: accesslog_als_1_1
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: accesslog_als_1_2
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: accesslog_als_1_2
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: accesslog_als_2_1
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: accesslog_als_2_1
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: accesslog_als_2_2
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: accesslog_als_2_2
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: accesslog_otel_0_3
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: otel-collector.monitoring.svc.cluster.local
+ portValue: 4317
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: accesslog_otel_0_3/backend/0
+ name: accesslog_otel_0_3
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: accesslog_otel_1_3
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: otel-collector.monitoring.svc.cluster.local
+ portValue: 4317
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: accesslog_otel_1_3/backend/0
+ name: accesslog_otel_1_3
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: accesslog_otel_2_3
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: otel-collector.monitoring.svc.cluster.local
+ portValue: 4317
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: accesslog_otel_2_3/backend/0
+ name: accesslog_otel_2_3
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-types.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-types.endpoints.yaml
new file mode 100644
index 00000000000..e9526ab5d90
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-types.endpoints.yaml
@@ -0,0 +1,84 @@
+- clusterName: direct-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: direct-route-dest/backend/0
+- clusterName: accesslog_als_0_1
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 10.240.0.10
+ portValue: 9090
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: accesslog_als_0_1/backend/0
+- clusterName: accesslog_als_0_2
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 10.240.0.10
+ portValue: 9090
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: accesslog_als_0_2/backend/0
+- clusterName: accesslog_als_1_1
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 10.240.0.10
+ portValue: 9090
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: accesslog_als_1_1/backend/0
+- clusterName: accesslog_als_1_2
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 10.240.0.10
+ portValue: 9090
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: accesslog_als_1_2/backend/0
+- clusterName: accesslog_als_2_1
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 10.240.0.10
+ portValue: 9090
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: accesslog_als_2_1/backend/0
+- clusterName: accesslog_als_2_2
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 10.240.0.10
+ portValue: 9090
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: accesslog_als_2_2/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-types.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-types.listeners.yaml
new file mode 100644
index 00000000000..dbb30726378
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-types.listeners.yaml
@@ -0,0 +1,300 @@
+- accessLog:
+ - name: envoy.access_loggers.file
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ logFormat:
+ textFormatSource:
+ inlineString: |
+ {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
+ path: /dev/stdout
+ - name: envoy.access_loggers.file
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ logFormat:
+ textFormatSource:
+ inlineString: |
+ this is a listener log
+ path: /dev/stdout
+ - filter:
+ responseFlagFilter:
+ flags:
+ - NR
+ name: envoy.access_loggers.file
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ logFormat:
+ textFormatSource:
+ inlineString: |
+ this is a Global log
+ path: /dev/stdout
+ - name: envoy.access_loggers.http_grpc
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig
+ additionalRequestHeadersToLog:
+ - x-client-ip-address
+ additionalResponseHeadersToLog:
+ - cache-control
+ additionalResponseTrailersToLog:
+ - expires
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ clusterName: accesslog_als_1_1
+ logName: accesslog
+ transportApiVersion: V3
+ - name: envoy.access_loggers.tcp_grpc
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.TcpGrpcAccessLogConfig
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ clusterName: accesslog_als_1_2
+ logName: envoy-gateway-system/test
+ transportApiVersion: V3
+ - filter:
+ responseFlagFilter:
+ flags:
+ - NR
+ name: envoy.access_loggers.http_grpc
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig
+ additionalRequestHeadersToLog:
+ - x-client-ip-address
+ additionalResponseHeadersToLog:
+ - cache-control
+ additionalResponseTrailersToLog:
+ - expires
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ clusterName: accesslog_als_2_1
+ logName: accesslog
+ transportApiVersion: V3
+ - filter:
+ responseFlagFilter:
+ flags:
+ - NR
+ name: envoy.access_loggers.tcp_grpc
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.TcpGrpcAccessLogConfig
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ clusterName: accesslog_als_2_2
+ logName: envoy-gateway-system/test
+ transportApiVersion: V3
+ - name: envoy.access_loggers.open_telemetry
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig
+ attributes:
+ values:
+ - key: k8s.namespace.name
+ value:
+ stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%'
+ - key: k8s.pod.name
+ value:
+ stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%'
+ body:
+ stringValue: |
+ this is a listener log
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ authority: otel-collector.monitoring.svc.cluster.local
+ clusterName: accesslog_otel_1_3
+ logName: otel_envoy_accesslog
+ transportApiVersion: V3
+ resourceAttributes:
+ values:
+ - key: k8s.cluster.name
+ value:
+ stringValue: cluster-1
+ - filter:
+ responseFlagFilter:
+ flags:
+ - NR
+ name: envoy.access_loggers.open_telemetry
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig
+ attributes:
+ values:
+ - key: k8s.namespace.name
+ value:
+ stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%'
+ - key: k8s.pod.name
+ value:
+ stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%'
+ body:
+ stringValue: |
+ this is a Global log
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ authority: otel-collector.monitoring.svc.cluster.local
+ clusterName: accesslog_otel_2_3
+ logName: otel_envoy_accesslog
+ transportApiVersion: V3
+ resourceAttributes:
+ values:
+ - key: k8s.cluster.name
+ value:
+ stringValue: cluster-1
+ address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ accessLog:
+ - name: envoy.access_loggers.file
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ logFormat:
+ textFormatSource:
+ inlineString: |
+ {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"}
+ path: /dev/stdout
+ - name: envoy.access_loggers.file
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ logFormat:
+ textFormatSource:
+ inlineString: |
+ this is a route log
+ path: /dev/stdout
+ - name: envoy.access_loggers.file
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ logFormat:
+ textFormatSource:
+ inlineString: |
+ this is a Global log
+ path: /dev/stdout
+ - name: envoy.access_loggers.http_grpc
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig
+ additionalRequestHeadersToLog:
+ - x-client-ip-address
+ additionalResponseHeadersToLog:
+ - cache-control
+ additionalResponseTrailersToLog:
+ - expires
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ clusterName: accesslog_als_0_1
+ logName: accesslog
+ transportApiVersion: V3
+ - name: envoy.access_loggers.tcp_grpc
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.TcpGrpcAccessLogConfig
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ clusterName: accesslog_als_0_2
+ logName: envoy-gateway-system/test
+ transportApiVersion: V3
+ - name: envoy.access_loggers.http_grpc
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig
+ additionalRequestHeadersToLog:
+ - x-client-ip-address
+ additionalResponseHeadersToLog:
+ - cache-control
+ additionalResponseTrailersToLog:
+ - expires
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ clusterName: accesslog_als_2_1
+ logName: accesslog
+ transportApiVersion: V3
+ - name: envoy.access_loggers.tcp_grpc
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.TcpGrpcAccessLogConfig
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ clusterName: accesslog_als_2_2
+ logName: envoy-gateway-system/test
+ transportApiVersion: V3
+ - name: envoy.access_loggers.open_telemetry
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig
+ attributes:
+ values:
+ - key: k8s.namespace.name
+ value:
+ stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%'
+ - key: k8s.pod.name
+ value:
+ stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%'
+ body:
+ stringValue: |
+ this is a route log
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ authority: otel-collector.monitoring.svc.cluster.local
+ clusterName: accesslog_otel_0_3
+ logName: otel_envoy_accesslog
+ transportApiVersion: V3
+ resourceAttributes:
+ values:
+ - key: k8s.cluster.name
+ value:
+ stringValue: cluster-1
+ - name: envoy.access_loggers.open_telemetry
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig
+ attributes:
+ values:
+ - key: k8s.namespace.name
+ value:
+ stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%'
+ - key: k8s.pod.name
+ value:
+ stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%'
+ body:
+ stringValue: |
+ this is a Global log
+ commonConfig:
+ grpcService:
+ envoyGrpc:
+ authority: otel-collector.monitoring.svc.cluster.local
+ clusterName: accesslog_otel_2_3
+ logName: otel_envoy_accesslog
+ transportApiVersion: V3
+ resourceAttributes:
+ values:
+ - key: k8s.cluster.name
+ value:
+ stringValue: cluster-1
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: envoy-gateway/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: envoy-gateway/gateway-1/http
+ name: envoy-gateway/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-types.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-types.routes.yaml
new file mode 100644
index 00000000000..084eabe4105
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-types.routes.yaml
@@ -0,0 +1,22 @@
+- ignorePortInHostMatching: true
+ name: envoy-gateway/gateway-1/http
+ virtualHosts:
+ - domains:
+ - '*'
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http/*
+ routes:
+ - match:
+ prefix: /
+ name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml
index 6ba4705c13f..6df53f6698c 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: direct-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,29 +21,31 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: accesslog/monitoring/envoy-als/port/9000
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: accesslog/monitoring/envoy-als/port/9000
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
- circuitBreakers:
thresholds:
- maxRetries: 1024
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -60,7 +62,6 @@
locality:
region: accesslog-0/backend/0
name: accesslog-0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
type: STRICT_DNS
@@ -68,4 +69,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.listeners.yaml
index 4eec559618e..541d20c663d 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.listeners.yaml
@@ -43,6 +43,7 @@
grpcService:
envoyGrpc:
clusterName: accesslog/monitoring/envoy-als/port/9000
+ logName: als
transportApiVersion: V3
- filter:
responseFlagFilter:
@@ -79,7 +80,7 @@
stringValue: cluster1
address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -119,6 +120,7 @@
grpcService:
envoyGrpc:
clusterName: accesslog/monitoring/envoy-als/port/9000
+ logName: als
transportApiVersion: V3
- name: envoy.access_loggers.open_telemetry
typedConfig:
@@ -169,9 +171,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.routes.yaml
index b214e8b05a3..ea343799ac1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.routes.yaml
@@ -5,8 +5,10 @@
- '*'
name: first-listener/*
routes:
- - directResponse:
- status: 500
- match:
+ - match:
prefix: /
name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml
index 6ba4705c13f..6df53f6698c 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: direct-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,29 +21,31 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: accesslog/monitoring/envoy-als/port/9000
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: accesslog/monitoring/envoy-als/port/9000
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
- circuitBreakers:
thresholds:
- maxRetries: 1024
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -60,7 +62,6 @@
locality:
region: accesslog-0/backend/0
name: accesslog-0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
type: STRICT_DNS
@@ -68,4 +69,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog.listeners.yaml
index 16609de576c..71f4affea97 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog.listeners.yaml
@@ -43,6 +43,7 @@
grpcService:
envoyGrpc:
clusterName: accesslog/monitoring/envoy-als/port/9000
+ logName: als
transportApiVersion: V3
- filter:
responseFlagFilter:
@@ -79,7 +80,7 @@
stringValue: cluster1
address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -119,6 +120,7 @@
grpcService:
envoyGrpc:
clusterName: accesslog/monitoring/envoy-als/port/9000
+ logName: als
transportApiVersion: V3
- name: envoy.access_loggers.open_telemetry
typedConfig:
@@ -169,9 +171,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog.routes.yaml
index b214e8b05a3..ea343799ac1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog.routes.yaml
@@ -5,8 +5,10 @@
- '*'
name: first-listener/*
routes:
- - directResponse:
- status: 500
- match:
+ - match:
prefix: /
name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.clusters.yaml
new file mode 100644
index 00000000000..b6e0c7f99af
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.clusters.yaml
@@ -0,0 +1,51 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-3/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-3/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.endpoints.yaml
new file mode 100644
index 00000000000..24596d841a3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.endpoints.yaml
@@ -0,0 +1,36 @@
+- clusterName: httproute/default/httproute-3/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-3/rule/0/backend/0
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.listeners.yaml
new file mode 100644
index 00000000000..907d28f78b7
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.listeners.yaml
@@ -0,0 +1,37 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.rbac
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: envoy-gateway/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: envoy-gateway/gateway-1/http
+ name: envoy-gateway/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.routes.yaml
new file mode 100644
index 00000000000..141d60a15dd
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-client-cidr.routes.yaml
@@ -0,0 +1,135 @@
+- ignorePortInHostMatching: true
+ name: envoy-gateway/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.example.com
+ name: envoy-gateway/gateway-1/http/www_example_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /test
+ name: httproute/default/httproute-3/rule/0/match/0/www_example_com
+ route:
+ cluster: httproute/default/httproute-3/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.rbac:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+ rbac:
+ matcher:
+ onNoMatch:
+ action:
+ name: default
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
+ - match:
+ pathSeparatedPrefix: /foo
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.rbac:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+ rbac:
+ matcher:
+ matcherList:
+ matchers:
+ - onMatch:
+ action:
+ name: deny-location-1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
+ predicate:
+ singlePredicate:
+ customMatch:
+ name: ip_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.ip.v3.Ip
+ cidrRanges:
+ - addressPrefix: 192.168.1.0
+ prefixLen: 24
+ - addressPrefix: 192.168.2.0
+ prefixLen: 24
+ statPrefix: client_ip
+ input:
+ name: client_ip
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput
+ - onMatch:
+ action:
+ name: deny-location-2
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
+ predicate:
+ singlePredicate:
+ customMatch:
+ name: ip_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.ip.v3.Ip
+ cidrRanges:
+ - addressPrefix: 10.75.1.0
+ prefixLen: 24
+ - addressPrefix: 10.75.2.0
+ prefixLen: 24
+ statPrefix: client_ip
+ input:
+ name: client_ip
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput
+ onNoMatch:
+ action:
+ name: default
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ name: ALLOW
+ - match:
+ pathSeparatedPrefix: /bar
+ name: httproute/default/httproute-2/rule/0/match/0/www_example_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.rbac:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+ rbac:
+ matcher:
+ matcherList:
+ matchers:
+ - onMatch:
+ action:
+ name: securitypolicy/envoy-gateway/policy-for-gateway/authorization/rule/0
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ name: ALLOW
+ predicate:
+ singlePredicate:
+ customMatch:
+ name: ip_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.ip.v3.Ip
+ cidrRanges:
+ - addressPrefix: 10.0.1.0
+ prefixLen: 24
+ - addressPrefix: 10.0.2.0
+ prefixLen: 24
+ statPrefix: client_ip
+ input:
+ name: client_ip
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput
+ onNoMatch:
+ action:
+ name: default
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.clusters.yaml
new file mode 100644
index 00000000000..66e1a3ca308
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.clusters.yaml
@@ -0,0 +1,104 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: two_example_com_443
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: two.example.com
+ portValue: 443
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: two_example_com_443/backend/0
+ name: two_example_com_443
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ validationContext:
+ trustedCa:
+ filename: /etc/ssl/certs/ca-certificates.crt
+ sni: two.example.com
+ type: STRICT_DNS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: one_example_com_443
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: one.example.com
+ portValue: 443
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: one_example_com_443/backend/0
+ name: one_example_com_443
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ validationContext:
+ trustedCa:
+ filename: /etc/ssl/certs/ca-certificates.crt
+ sni: one.example.com
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.endpoints.yaml
new file mode 100644
index 00000000000..05442a9a15b
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.endpoints.yaml
@@ -0,0 +1,24 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.listeners.yaml
new file mode 100644
index 00000000000..2bfa9b51303
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.listeners.yaml
@@ -0,0 +1,78 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.jwt_authn
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
+ providers:
+ httproute/default/httproute-1/rule/0/match/0/www_example_com/example1:
+ audiences:
+ - two.foo.com
+ forward: true
+ issuer: https://two.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example1
+ remoteJwks:
+ asyncFetch: {}
+ cacheDuration: 300s
+ httpUri:
+ cluster: two_example_com_443
+ timeout: 10s
+ uri: https://two.example.com/jwt/public-key/jwks.json
+ httproute/default/httproute-2/rule/0/match/0/www_example_com/example1:
+ audiences:
+ - one.foo.com
+ forward: true
+ issuer: https://one.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example1
+ remoteJwks:
+ asyncFetch: {}
+ cacheDuration: 300s
+ httpUri:
+ cluster: one_example_com_443
+ timeout: 10s
+ uri: https://one.example.com/jwt/public-key/jwks.json
+ requirementMap:
+ httproute/default/httproute-1/rule/0/match/0/www_example_com:
+ providerName: httproute/default/httproute-1/rule/0/match/0/www_example_com/example1
+ httproute/default/httproute-2/rule/0/match/0/www_example_com:
+ providerName: httproute/default/httproute-2/rule/0/match/0/www_example_com/example1
+ - name: envoy.filters.http.rbac
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: envoy-gateway/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: envoy-gateway/gateway-1/http
+ name: envoy-gateway/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.routes.yaml
new file mode 100644
index 00000000000..5a465cded12
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-claim.routes.yaml
@@ -0,0 +1,185 @@
+- ignorePortInHostMatching: true
+ name: envoy-gateway/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.example.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http/www_example_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.jwt_authn:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.PerRouteConfig
+ requirementName: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ envoy.filters.http.rbac:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+ rbac:
+ matcher:
+ matcherList:
+ matchers:
+ - onMatch:
+ action:
+ name: allow-claim-roles
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
+ predicate:
+ orMatcher:
+ predicate:
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ stringMatch:
+ exact: alice
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: example1
+ - key: user
+ - key: name
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ stringMatch:
+ exact: bob
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: example1
+ - key: user
+ - key: name
+ onNoMatch:
+ action:
+ name: default
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
+ - match:
+ pathSeparatedPrefix: /bar
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_example_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.jwt_authn:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.PerRouteConfig
+ requirementName: httproute/default/httproute-2/rule/0/match/0/www_example_com
+ envoy.filters.http.rbac:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+ rbac:
+ matcher:
+ matcherList:
+ matchers:
+ - onMatch:
+ action:
+ name: allow-claim-roles
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
+ predicate:
+ andMatcher:
+ predicate:
+ - orMatcher:
+ predicate:
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: admin
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: example1
+ - key: roles
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: superuser
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: example1
+ - key: roles
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ stringMatch:
+ exact: engineering
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: example1
+ - key: department
+ onNoMatch:
+ action:
+ name: default
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.clusters.yaml
new file mode 100644
index 00000000000..66e1a3ca308
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.clusters.yaml
@@ -0,0 +1,104 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: two_example_com_443
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: two.example.com
+ portValue: 443
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: two_example_com_443/backend/0
+ name: two_example_com_443
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ validationContext:
+ trustedCa:
+ filename: /etc/ssl/certs/ca-certificates.crt
+ sni: two.example.com
+ type: STRICT_DNS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: one_example_com_443
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: one.example.com
+ portValue: 443
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: one_example_com_443/backend/0
+ name: one_example_com_443
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ validationContext:
+ trustedCa:
+ filename: /etc/ssl/certs/ca-certificates.crt
+ sni: one.example.com
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.endpoints.yaml
new file mode 100644
index 00000000000..05442a9a15b
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.endpoints.yaml
@@ -0,0 +1,24 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.listeners.yaml
new file mode 100644
index 00000000000..2bfa9b51303
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.listeners.yaml
@@ -0,0 +1,78 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.jwt_authn
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
+ providers:
+ httproute/default/httproute-1/rule/0/match/0/www_example_com/example1:
+ audiences:
+ - two.foo.com
+ forward: true
+ issuer: https://two.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example1
+ remoteJwks:
+ asyncFetch: {}
+ cacheDuration: 300s
+ httpUri:
+ cluster: two_example_com_443
+ timeout: 10s
+ uri: https://two.example.com/jwt/public-key/jwks.json
+ httproute/default/httproute-2/rule/0/match/0/www_example_com/example1:
+ audiences:
+ - one.foo.com
+ forward: true
+ issuer: https://one.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example1
+ remoteJwks:
+ asyncFetch: {}
+ cacheDuration: 300s
+ httpUri:
+ cluster: one_example_com_443
+ timeout: 10s
+ uri: https://one.example.com/jwt/public-key/jwks.json
+ requirementMap:
+ httproute/default/httproute-1/rule/0/match/0/www_example_com:
+ providerName: httproute/default/httproute-1/rule/0/match/0/www_example_com/example1
+ httproute/default/httproute-2/rule/0/match/0/www_example_com:
+ providerName: httproute/default/httproute-2/rule/0/match/0/www_example_com/example1
+ - name: envoy.filters.http.rbac
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: envoy-gateway/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: envoy-gateway/gateway-1/http
+ name: envoy-gateway/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.routes.yaml
new file mode 100644
index 00000000000..cfb4a62ec65
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-jwt-scope.routes.yaml
@@ -0,0 +1,149 @@
+- ignorePortInHostMatching: true
+ name: envoy-gateway/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.example.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http/www_example_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.jwt_authn:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.PerRouteConfig
+ requirementName: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ envoy.filters.http.rbac:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+ rbac:
+ matcher:
+ matcherList:
+ matchers:
+ - onMatch:
+ action:
+ name: allow-scope-foo-bar
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
+ predicate:
+ andMatcher:
+ predicate:
+ - singlePredicate:
+ customMatch:
+ name: scope_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: foo
+ input:
+ name: scope
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: example1
+ - key: scope
+ - singlePredicate:
+ customMatch:
+ name: scope_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: bar
+ input:
+ name: scope
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: example1
+ - key: scope
+ onNoMatch:
+ action:
+ name: default
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
+ - match:
+ pathSeparatedPrefix: /bar
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_example_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.jwt_authn:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.PerRouteConfig
+ requirementName: httproute/default/httproute-2/rule/0/match/0/www_example_com
+ envoy.filters.http.rbac:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+ rbac:
+ matcher:
+ matcherList:
+ matchers:
+ - onMatch:
+ action:
+ name: allow-scope-foo
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
+ predicate:
+ singlePredicate:
+ customMatch:
+ name: scope_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: foo
+ input:
+ name: scope
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: example1
+ - key: scope
+ onNoMatch:
+ action:
+ name: default
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.clusters.yaml
new file mode 100644
index 00000000000..c24d059eeaa
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.clusters.yaml
@@ -0,0 +1,17 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.endpoints.yaml
new file mode 100644
index 00000000000..29bb6b4e444
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.listeners.yaml
new file mode 100644
index 00000000000..907d28f78b7
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.listeners.yaml
@@ -0,0 +1,37 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.rbac
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: envoy-gateway/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: envoy-gateway/gateway-1/http
+ name: envoy-gateway/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.routes.yaml
new file mode 100644
index 00000000000..2b9a4906343
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.routes.yaml
@@ -0,0 +1,256 @@
+- ignorePortInHostMatching: true
+ name: envoy-gateway/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.example.com
+ name: envoy-gateway/gateway-1/http/www_example_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.rbac:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+ rbac:
+ matcher:
+ matcherList:
+ matchers:
+ - onMatch:
+ action:
+ name: allow-rule-1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ name: ALLOW
+ predicate:
+ andMatcher:
+ predicate:
+ - singlePredicate:
+ customMatch:
+ name: ip_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.ip.v3.Ip
+ cidrRanges:
+ - addressPrefix: 192.168.1.0
+ prefixLen: 24
+ - addressPrefix: 192.168.2.0
+ prefixLen: 24
+ statPrefix: client_ip
+ input:
+ name: client_ip
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput
+ - singlePredicate:
+ customMatch:
+ name: scope_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: foo
+ input:
+ name: scope
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: https://one.example.com
+ - key: scope
+ - orMatcher:
+ predicate:
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: admin
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: https://one.example.com
+ - key: roles
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: superuser
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: https://one.example.com
+ - key: roles
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ stringMatch:
+ exact: engineering
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: https://one.example.com
+ - key: department
+ - onMatch:
+ action:
+ name: allow-rule-2
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ name: ALLOW
+ predicate:
+ andMatcher:
+ predicate:
+ - singlePredicate:
+ customMatch:
+ name: ip_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.ip.v3.Ip
+ cidrRanges:
+ - addressPrefix: 10.0.1.0
+ prefixLen: 24
+ - addressPrefix: 10.0.2.0
+ prefixLen: 24
+ statPrefix: client_ip
+ input:
+ name: client_ip
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput
+ - singlePredicate:
+ customMatch:
+ name: scope_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: for
+ input:
+ name: scope
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: https://two.example.com
+ - key: scope
+ - singlePredicate:
+ customMatch:
+ name: scope_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: bar
+ input:
+ name: scope
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: https://two.example.com
+ - key: scope
+ - orMatcher:
+ predicate:
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: admin
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: https://two.example.com
+ - key: roles
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: superuser
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: https://two.example.com
+ - key: roles
+ - orMatcher:
+ predicate:
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ stringMatch:
+ exact: alice
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: https://two.example.com
+ - key: name
+ - singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ stringMatch:
+ exact: bob
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: https://two.example.com
+ - key: name
+ onNoMatch:
+ action:
+ name: default
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization.clusters.yaml
index b3f75f0e04e..bd69f5a8445 100644
--- a/internal/xds/translator/testdata/out/xds-ir/authorization.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization.clusters.yaml
@@ -12,7 +12,6 @@
serviceName: httproute/default/httproute-3/rule/0
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-3/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -29,7 +28,6 @@
serviceName: httproute/default/httproute-1/rule/0
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-1/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -46,6 +44,5 @@
serviceName: httproute/default/httproute-2/rule/0
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-2/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization.listeners.yaml
index 0fa87744bf1..907d28f78b7 100644
--- a/internal/xds/translator/testdata/out/xds-ir/authorization.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization.listeners.yaml
@@ -30,9 +30,8 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-1/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway/gateway-1/http
- drainType: MODIFY_ONLY
name: envoy-gateway/gateway-1/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.clusters.yaml
index 8b9fea6228f..baa860c9ffe 100644
--- a/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 100000000
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 100000000
type: EDS
- circuitBreakers:
@@ -38,14 +38,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: udp-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: udp-route-dest
- outlierDetection: {}
- perConnectionBufferLimitBytes: 100000000
+ perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.listeners.yaml
index a7a16c3b3e9..688cef1f74b 100644
--- a/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,30 +27,28 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-dest
- statPrefix: tcp
+ statPrefix: tcp-10081
name: tcp-route-dest
name: second-listener
perConnectionBufferLimitBytes: 1500
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
protocol: UDP
listenerFilters:
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.clusters.yaml
new file mode 100644
index 00000000000..970324b2c9d
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.clusters.yaml
@@ -0,0 +1,99 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: envoyextensionpolicy/default/policy-for-http-route/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: envoyextensionpolicy/default/policy-for-http-route/0
+ perConnectionBufferLimitBytes: 32768
+ transportSocketMatches:
+ - match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/0
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/0
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext:
+ matchTypedSubjectAltNames:
+ - matcher:
+ exact: grpc-backend
+ sanType: DNS
+ validationContextSdsSecretConfig:
+ name: policy-btls-grpc/envoy-gateway-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ sni: grpc-backend
+ - match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext:
+ matchTypedSubjectAltNames:
+ - matcher:
+ exact: ip-backend
+ sanType: DNS
+ validationContextSdsSecretConfig:
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ sni: ip-backend
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.endpoints.yaml
new file mode 100644
index 00000000000..30f113b0a73
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.endpoints.yaml
@@ -0,0 +1,66 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
+- clusterName: envoyextensionpolicy/default/policy-for-http-route/0
+ endpoints:
+ - loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/0
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 8.8.8.8
+ portValue: 9000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/1
+ priority: 1
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.1.1.1
+ portValue: 3001
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/2
+ priority: 1
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 2.2.2.2
+ portValue: 3443
+ loadBalancingWeight: 1
+ metadata:
+ filterMetadata:
+ envoy.transport_socket_match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/3
+ priority: 1
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.listeners.yaml
new file mode 100644
index 00000000000..55e2fde715b
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.listeners.yaml
@@ -0,0 +1,48 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
+ grpcService:
+ envoyGrpc:
+ authority: grpc-backend.envoy-gateway:8000
+ clusterName: envoyextensionpolicy/default/policy-for-http-route/0
+ timeout: 10s
+ processingMode:
+ requestHeaderMode: SKIP
+ requestTrailerMode: SKIP
+ responseHeaderMode: SKIP
+ responseTrailerMode: SKIP
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: default/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: default/gateway-1/http
+ name: default/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.routes.yaml
new file mode 100644
index 00000000000..e5e50ccde27
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.routes.yaml
@@ -0,0 +1,59 @@
+- ignorePortInHostMatching: true
+ name: default/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.foo.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http/www_foo_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - domains:
+ - www.bar.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http/www_bar_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /bar
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.secrets.yaml
new file mode 100644
index 00000000000..387926a79f3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.secrets.yaml
@@ -0,0 +1,8 @@
+- name: policy-btls-grpc/envoy-gateway-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+- name: policy-btls-backend-ip/envoy-gateway-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
diff --git a/internal/xds/translator/testdata/out/xds-ir/basic-auth.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/basic-auth.clusters.yaml
index e4e5b8994bc..c60ba5e19ae 100644
--- a/internal/xds/translator/testdata/out/xds-ir/basic-auth.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/basic-auth.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-1/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-1/rule/1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-1/rule/1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,14 +38,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-2/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml
index 4127a7acbf3..a7accc0ef6c 100644
--- a/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml
@@ -33,9 +33,8 @@
resourceApiVersion: V3
routeConfigName: default/gateway-1/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: default/gateway-1/http
- drainType: MODIFY_ONLY
name: default/gateway-1/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/circuit-breaker.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/circuit-breaker.clusters.yaml
index 90636e8ffe1..1767baed59c 100644
--- a/internal/xds/translator/testdata/out/xds-ir/circuit-breaker.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/circuit-breaker.clusters.yaml
@@ -7,15 +7,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
diff --git a/internal/xds/translator/testdata/out/xds-ir/circuit-breaker.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/circuit-breaker.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/circuit-breaker.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/circuit-breaker.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/client-buffer-limit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/client-buffer-limit.clusters.yaml
index 5aa4727b18a..1b8a0dcfcdf 100644
--- a/internal/xds/translator/testdata/out/xds-ir/client-buffer-limit.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/client-buffer-limit.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/client-buffer-limit.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/client-buffer-limit.listeners.yaml
index 095074165f3..9ae223623db 100644
--- a/internal/xds/translator/testdata/out/xds-ir/client-buffer-limit.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/client-buffer-limit.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,24 +27,22 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 1500
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-dest
- statPrefix: tcp
+ statPrefix: tcp-10081
name: tcp-route-dest
name: second-listener
perConnectionBufferLimitBytes: 1500
diff --git a/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.clusters.yaml
index a89644e62d9..121c8aad8bb 100644
--- a/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,14 +38,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.listeners.yaml
index 21f93d68a49..4515aa70761 100644
--- a/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 8081
defaultFilterChain:
filters:
@@ -25,16 +25,15 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8081
useRemoteAddress: true
xffNumTrustedHops: 2
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 8082
defaultFilterChain:
filters:
@@ -65,15 +64,14 @@
resourceApiVersion: V3
routeConfigName: second-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8082
useRemoteAddress: false
name: second-listener
- drainType: MODIFY_ONLY
name: second-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 8083
defaultFilterChain:
filters:
@@ -106,9 +104,8 @@
resourceApiVersion: V3
routeConfigName: third-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8083
useRemoteAddress: false
name: third-listener
- drainType: MODIFY_ONLY
name: third-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/client-timeout.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/client-timeout.clusters.yaml
index d65e267ad7d..ba595752d94 100644
--- a/internal/xds/translator/testdata/out/xds-ir/client-timeout.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/client-timeout.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/client-timeout.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/client-timeout.listeners.yaml
index 2d1a3e61e38..59b7902b54a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/client-timeout.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/client-timeout.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -29,17 +29,15 @@
routeConfigName: first-listener
requestTimeout: 5s
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
@@ -47,7 +45,7 @@
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: second-route-dest
idleTimeout: 1200s
- statPrefix: tcp
+ statPrefix: tcp-10081
name: second-route
name: second-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/cors.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/cors.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/cors.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/cors.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/cors.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/cors.listeners.yaml
index e8299cdce42..e43d6e27f7a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/cors.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/cors.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -30,9 +30,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/cors.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/cors.routes.yaml
index 93bfb4d3c15..12c4fce7778 100644
--- a/internal/xds/translator/testdata/out/xds-ir/cors.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/cors.routes.yaml
@@ -17,7 +17,7 @@
'@type': type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicy
allowCredentials: true
allowHeaders: x-header-1, x-header-2
- allowMethods: GET, POST
+ allowMethods: '*'
allowOriginStringMatch:
- safeRegex:
regex: '*.example.com'
diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.clusters.yaml
index 0e10ab58f0c..6d5d6f5e1f3 100644
--- a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.clusters.yaml
@@ -4,7 +4,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -21,7 +21,6 @@
locality:
region: one_example_com_443/backend/0
name: one_example_com_443
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
@@ -40,7 +39,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -57,7 +56,6 @@
locality:
region: two_example_com_80/backend/0
name: two_example_com_80
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml
index 5f54802ba05..9758fe7f17c 100644
--- a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml
@@ -73,7 +73,10 @@
headerName: one-route-example-key
forward: true
issuer: https://one.example.com
- payloadInMetadata: https://one.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example1
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -81,7 +84,6 @@
cluster: one_example_com_443
timeout: 10s
uri: https://one.example.com/jwt/public-key/jwks.json
- retryPolicy: {}
httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com/example2:
audiences:
- two.foo.com
@@ -90,7 +92,10 @@
headerName: two-route-example-key
forward: true
issuer: http://two.example.com
- payloadInMetadata: http://two.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example2
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -98,7 +103,6 @@
cluster: two_example_com_80
timeout: 10s
uri: http://two.example.com/jwt/public-key/jwks.json
- retryPolicy: {}
requirementMap:
httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com:
requiresAny:
@@ -118,9 +122,8 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-1/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway/gateway-1/http
- drainType: MODIFY_ONLY
name: envoy-gateway/gateway-1/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-response.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-response.clusters.yaml
new file mode 100644
index 00000000000..c24d059eeaa
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/custom-response.clusters.yaml
@@ -0,0 +1,17 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-response.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-response.endpoints.yaml
new file mode 100644
index 00000000000..29bb6b4e444
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/custom-response.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-response.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-response.listeners.yaml
new file mode 100644
index 00000000000..19c56586960
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/custom-response.listeners.yaml
@@ -0,0 +1,130 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.custom_response/backendtrafficpolicy/default/policy-for-gateway
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.custom_response.v3.CustomResponse
+ customResponseMatcher:
+ matcherList:
+ matchers:
+ - onMatch:
+ action:
+ name: backendtrafficpolicy/default/policy-for-gateway/responseoverride/rule/0
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.custom_response.local_response_policy.v3.LocalResponsePolicy
+ body:
+ inlineString: gateway-1 Not Found
+ responseHeadersToAdd:
+ - appendAction: OVERWRITE_IF_EXISTS_OR_ADD
+ header:
+ key: Content-Type
+ value: text/plain
+ predicate:
+ singlePredicate:
+ input:
+ name: http-response-status-code-match-input
+ typedConfig:
+ '@type': type.googleapis.com/envoy.type.matcher.v3.HttpResponseStatusCodeMatchInput
+ valueMatch:
+ exact: "404"
+ - onMatch:
+ action:
+ name: backendtrafficpolicy/default/policy-for-gateway/responseoverride/rule/1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.custom_response.local_response_policy.v3.LocalResponsePolicy
+ body:
+ inlineString: |
+ {
+ "error": "Internal Server Error"
+ }
+ responseHeadersToAdd:
+ - appendAction: OVERWRITE_IF_EXISTS_OR_ADD
+ header:
+ key: Content-Type
+ value: application/json
+ predicate:
+ orMatcher:
+ predicate:
+ - singlePredicate:
+ input:
+ name: http-response-status-code-match-input
+ typedConfig:
+ '@type': type.googleapis.com/envoy.type.matcher.v3.HttpResponseStatusCodeMatchInput
+ valueMatch:
+ exact: "500"
+ - singlePredicate:
+ customMatch:
+ name: cel-matcher
+ typedConfig:
+ '@type': type.googleapis.com/xds.type.matcher.v3.CelMatcher
+ exprMatch:
+ parsedExpr:
+ expr:
+ callExpr:
+ args:
+ - callExpr:
+ args:
+ - id: "2"
+ selectExpr:
+ field: code
+ operand:
+ id: "1"
+ identExpr:
+ name: response
+ - constExpr:
+ int64Value: "501"
+ id: "4"
+ function: _>=_
+ id: "3"
+ - callExpr:
+ args:
+ - id: "6"
+ selectExpr:
+ field: code
+ operand:
+ id: "5"
+ identExpr:
+ name: response
+ - constExpr:
+ int64Value: "511"
+ id: "8"
+ function: _<=_
+ id: "7"
+ function: _&&_
+ id: "9"
+ input:
+ name: http-attributes-cel-match-input
+ typedConfig:
+ '@type': type.googleapis.com/xds.type.matcher.v3.HttpAttributesCelMatchInput
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: default/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: default/gateway-1/http
+ name: default/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-response.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-response.routes.yaml
new file mode 100644
index 00000000000..8262bb6f325
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/custom-response.routes.yaml
@@ -0,0 +1,33 @@
+- ignorePortInHostMatching: true
+ name: default/gateway-1/http
+ virtualHosts:
+ - domains:
+ - '*'
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http/*
+ routes:
+ - match:
+ prefix: /
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/-1/*
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.custom_response/backendtrafficpolicy/default/policy-for-gateway:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.clusters.yaml
new file mode 100644
index 00000000000..3ff821f5efb
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.clusters.yaml
@@ -0,0 +1,110 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/1
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/1
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: primary.foo.com
+ portValue: 9000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/default/policy-for-http-route-1/default/grpc-backend/backend/0
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: primary.foo.com
+ portValue: 80
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend/backend/0
+ name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.endpoints.yaml
new file mode 100644
index 00000000000..bf9f0023789
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.endpoints.yaml
@@ -0,0 +1,36 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-1/rule/1
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/1/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.listeners.yaml
new file mode 100644
index 00000000000..0ccea8c2bcb
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.listeners.yaml
@@ -0,0 +1,69 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
+ allowedHeaders:
+ patterns:
+ - exact: header1
+ ignoreCase: true
+ - exact: header2
+ ignoreCase: true
+ grpcService:
+ envoyGrpc:
+ authority: primary.foo.com
+ clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ timeout: 10s
+ transportApiVersion: V3
+ - disabled: true
+ name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
+ failureModeAllow: true
+ httpService:
+ authorizationResponse:
+ allowedUpstreamHeaders:
+ patterns:
+ - exact: header1
+ ignoreCase: true
+ - exact: header2
+ ignoreCase: true
+ pathPrefix: /auth
+ serverUri:
+ cluster: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ timeout: 10s
+ uri: http://primary.foo.com/auth
+ transportApiVersion: V3
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: default/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: default/gateway-1/http
+ name: default/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.routes.yaml
new file mode 100644
index 00000000000..08edfc3c406
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.routes.yaml
@@ -0,0 +1,44 @@
+- ignorePortInHostMatching: true
+ name: default/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.foo.com
+ name: default/gateway-1/http/www_foo_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo1
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - match:
+ pathSeparatedPrefix: /foo2
+ name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/1
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - domains:
+ - www.bar.com
+ name: default/gateway-1/http/www_bar_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /bar
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.clusters.yaml
new file mode 100644
index 00000000000..3ff821f5efb
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.clusters.yaml
@@ -0,0 +1,110 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/1
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/1
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: primary.foo.com
+ portValue: 9000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/default/policy-for-http-route-1/default/grpc-backend/backend/0
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: primary.foo.com
+ portValue: 80
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend/backend/0
+ name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.endpoints.yaml
new file mode 100644
index 00000000000..bf9f0023789
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.endpoints.yaml
@@ -0,0 +1,36 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-1/rule/1
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/1/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.listeners.yaml
new file mode 100644
index 00000000000..84bea029d0b
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.listeners.yaml
@@ -0,0 +1,71 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
+ allowedHeaders:
+ patterns:
+ - exact: header1
+ ignoreCase: true
+ - exact: header2
+ ignoreCase: true
+ grpcService:
+ envoyGrpc:
+ authority: primary.foo.com
+ clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ timeout: 10s
+ transportApiVersion: V3
+ - disabled: true
+ name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
+ failureModeAllow: true
+ httpService:
+ authorizationResponse:
+ allowedUpstreamHeaders:
+ patterns:
+ - exact: header1
+ ignoreCase: true
+ - exact: header2
+ ignoreCase: true
+ pathPrefix: /auth
+ serverUri:
+ cluster: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ timeout: 10s
+ uri: http://primary.foo.com/auth
+ transportApiVersion: V3
+ withRequestBody:
+ maxRequestBytes: 32768
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: default/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: default/gateway-1/http
+ name: default/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.routes.yaml
new file mode 100644
index 00000000000..08edfc3c406
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-body.routes.yaml
@@ -0,0 +1,44 @@
+- ignorePortInHostMatching: true
+ name: default/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.foo.com
+ name: default/gateway-1/http/www_foo_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo1
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - match:
+ pathSeparatedPrefix: /foo2
+ name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/1
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - domains:
+ - www.bar.com
+ name: default/gateway-1/http/www_bar_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /bar
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.clusters.yaml
new file mode 100644
index 00000000000..3ff821f5efb
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.clusters.yaml
@@ -0,0 +1,110 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/1
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/1
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: primary.foo.com
+ portValue: 9000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/default/policy-for-http-route-1/default/grpc-backend/backend/0
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: primary.foo.com
+ portValue: 80
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend/backend/0
+ name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.endpoints.yaml
new file mode 100644
index 00000000000..bf9f0023789
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.endpoints.yaml
@@ -0,0 +1,36 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-1/rule/1
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/1/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.listeners.yaml
new file mode 100644
index 00000000000..e2054562760
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.listeners.yaml
@@ -0,0 +1,70 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
+ allowedHeaders:
+ patterns:
+ - exact: header1
+ ignoreCase: true
+ - exact: header2
+ ignoreCase: true
+ grpcService:
+ envoyGrpc:
+ authority: primary.foo.com
+ clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ timeout: 10s
+ transportApiVersion: V3
+ - disabled: true
+ name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
+ clearRouteCache: true
+ failureModeAllow: true
+ httpService:
+ authorizationResponse:
+ allowedUpstreamHeaders:
+ patterns:
+ - exact: header1
+ ignoreCase: true
+ - exact: header2
+ ignoreCase: true
+ pathPrefix: /auth
+ serverUri:
+ cluster: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ timeout: 10s
+ uri: http://primary.foo.com/auth
+ transportApiVersion: V3
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: default/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: default/gateway-1/http
+ name: default/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.routes.yaml
new file mode 100644
index 00000000000..08edfc3c406
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-recomputation.routes.yaml
@@ -0,0 +1,44 @@
+- ignorePortInHostMatching: true
+ name: default/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.foo.com
+ name: default/gateway-1/http/www_foo_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo1
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - match:
+ pathSeparatedPrefix: /foo2
+ name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/1
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - domains:
+ - www.bar.com
+ name: default/gateway-1/http/www_bar_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /bar
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml
index cf4fbc9b274..4b69123192a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-1/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-1/rule/1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-1/rule/1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-2/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,36 +55,38 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
- circuitBreakers:
thresholds:
- maxRetries: 1024
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.endpoints.yaml
index 2c0f91a63f3..701d34b9675 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.endpoints.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.endpoints.yaml
@@ -36,6 +36,16 @@
region: httproute/default/httproute-2/rule/0/backend/0
- clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 8.8.4.4
+ portValue: 9001
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/default/policy-for-http-route-1/default/grpc-backend/backend/0
- lbEndpoints:
- endpoint:
address:
@@ -45,7 +55,7 @@
loadBalancingWeight: 1
loadBalancingWeight: 1
locality:
- region: securitypolicy/default/policy-for-http-route-1/default/grpc-backend/backend/0
+ region: securitypolicy/default/policy-for-http-route-1/default/grpc-backend/backend/1
- clusterName: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
endpoints:
- lbEndpoints:
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml
index c8b861fe1a7..84b95081c80 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml
@@ -62,9 +62,8 @@
resourceApiVersion: V3
routeConfigName: default/gateway-1/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: default/gateway-1/http
- drainType: MODIFY_ONLY
name: default/gateway-1/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.clusters.yaml
new file mode 100644
index 00000000000..fc5d51a1aea
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.clusters.yaml
@@ -0,0 +1,136 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxConnections: 2048
+ maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 15s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: envoyextensionpolicy/default/policy-for-http-route/0
+ ignoreHealthOnHostRemoval: true
+ name: envoyextensionpolicy/default/policy-for-http-route/0
+ outlierDetection:
+ baseEjectionTime: 30s
+ consecutive5xx: 5
+ consecutiveGatewayFailure: 4
+ consecutiveLocalOriginFailure: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ perConnectionBufferLimitBytes: 20971520
+ roundRobinLbConfig:
+ slowStartConfig:
+ slowStartWindow: 5s
+ transportSocket:
+ name: envoy.transport_sockets.upstream_proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport
+ config:
+ version: V2
+ transportSocket:
+ name: envoy.transport_sockets.raw_buffer
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer
+ transportSocketMatches:
+ - match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/0
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/0
+ transportSocket:
+ name: envoy.transport_sockets.upstream_proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport
+ config:
+ version: V2
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext:
+ matchTypedSubjectAltNames:
+ - matcher:
+ exact: grpc-backend
+ sanType: DNS
+ validationContextSdsSecretConfig:
+ name: policy-btls-grpc/envoy-gateway-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ sni: grpc-backend
+ - match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ transportSocket:
+ name: envoy.transport_sockets.upstream_proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport
+ config:
+ version: V2
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext:
+ matchTypedSubjectAltNames:
+ - matcher:
+ exact: ip-backend
+ sanType: DNS
+ validationContextSdsSecretConfig:
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ sni: ip-backend
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 2097152
+ initialStreamWindowSize: 131072
+ maxConcurrentStreams: 200
+ overrideStreamErrorOnInvalidHttpMessage: true
+ upstreamConnectionOptions:
+ tcpKeepalive:
+ keepaliveProbes: 7
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.endpoints.yaml
new file mode 100644
index 00000000000..a3d4fd4dc11
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.endpoints.yaml
@@ -0,0 +1,63 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
+- clusterName: envoyextensionpolicy/default/policy-for-http-route/0
+ endpoints:
+ - loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/0
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 8.8.8.8
+ portValue: 9000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/1
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.1.1.1
+ portValue: 3001
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/2
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 2.2.2.2
+ portValue: 3443
+ loadBalancingWeight: 1
+ metadata:
+ filterMetadata:
+ envoy.transport_socket_match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/3
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml
new file mode 100644
index 00000000000..55e2fde715b
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml
@@ -0,0 +1,48 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
+ grpcService:
+ envoyGrpc:
+ authority: grpc-backend.envoy-gateway:8000
+ clusterName: envoyextensionpolicy/default/policy-for-http-route/0
+ timeout: 10s
+ processingMode:
+ requestHeaderMode: SKIP
+ requestTrailerMode: SKIP
+ responseHeaderMode: SKIP
+ responseTrailerMode: SKIP
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: default/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: default/gateway-1/http
+ name: default/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml
new file mode 100644
index 00000000000..e5e50ccde27
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml
@@ -0,0 +1,59 @@
+- ignorePortInHostMatching: true
+ name: default/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.foo.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http/www_foo_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - domains:
+ - www.bar.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http/www_bar_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /bar
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.secrets.yaml
new file mode 100644
index 00000000000..387926a79f3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.secrets.yaml
@@ -0,0 +1,8 @@
+- name: policy-btls-grpc/envoy-gateway-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+- name: policy-btls-backend-ip/envoy-gateway-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml
index 08b38495e69..14ff9d61dfd 100755
--- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-1/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-2/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,85 +38,93 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
- circuitBreakers:
thresholds:
- maxRetries: 1024
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
- circuitBreakers:
thresholds:
- maxRetries: 1024
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
- circuitBreakers:
thresholds:
- maxRetries: 1024
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml
index 8e85e79cf9e..a75f1ccc268 100755
--- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml
@@ -32,6 +32,11 @@
responseBodyMode: STREAMED
responseHeaderMode: SKIP
responseTrailerMode: SKIP
+ requestAttributes:
+ - xds.route_metadata
+ - connection.requested_server_name
+ responseAttributes:
+ - request.path
- disabled: true
name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-1/extproc/0
typedConfig:
@@ -78,6 +83,11 @@
requestTrailerMode: SKIP
responseHeaderMode: SKIP
responseTrailerMode: SKIP
+ requestAttributes:
+ - xds.route_metadata
+ - connection.requested_server_name
+ responseAttributes:
+ - request.path
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
@@ -91,9 +101,8 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-1/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway/gateway-1/http
- drainType: MODIFY_ONLY
name: envoy-gateway/gateway-1/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/fault-injection.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/fault-injection.clusters.yaml
index 03e10ccd7fc..cc411266ad8 100644
--- a/internal/xds/translator/testdata/out/xds-ir/fault-injection.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/fault-injection.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,15 +55,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fourth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -72,14 +72,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fifth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fifth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/fault-injection.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/fault-injection.listeners.yaml
index e74a1df4287..72f0a0a1239 100644
--- a/internal/xds/translator/testdata/out/xds-ir/fault-injection.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/fault-injection.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -30,9 +30,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/headers-with-preserve-x-request-id.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/headers-with-preserve-x-request-id.clusters.yaml
index d65e267ad7d..ba595752d94 100755
--- a/internal/xds/translator/testdata/out/xds-ir/headers-with-preserve-x-request-id.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/headers-with-preserve-x-request-id.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/headers-with-preserve-x-request-id.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/headers-with-preserve-x-request-id.listeners.yaml
index c6a46e0f9c1..de527446ae0 100644
--- a/internal/xds/translator/testdata/out/xds-ir/headers-with-preserve-x-request-id.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/headers-with-preserve-x-request-id.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 8081
defaultFilterChain:
filters:
@@ -26,15 +26,14 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8081
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 8082
defaultFilterChain:
filters:
@@ -59,9 +58,8 @@
resourceApiVersion: V3
routeConfigName: second-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8082
useRemoteAddress: true
name: second-listener
- drainType: MODIFY_ONLY
name: second-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/headers-with-underscores-action.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/headers-with-underscores-action.clusters.yaml
index 7a7e90de25b..dba5fc4a3cd 100755
--- a/internal/xds/translator/testdata/out/xds-ir/headers-with-underscores-action.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/headers-with-underscores-action.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,14 +55,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fourth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/headers-with-underscores-action.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/headers-with-underscores-action.listeners.yaml
index 2a31352ab37..d0509c239cf 100644
--- a/internal/xds/translator/testdata/out/xds-ir/headers-with-underscores-action.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/headers-with-underscores-action.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 8081
defaultFilterChain:
filters:
@@ -25,15 +25,14 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8081
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 8082
defaultFilterChain:
filters:
@@ -57,15 +56,14 @@
resourceApiVersion: V3
routeConfigName: second-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8082
useRemoteAddress: true
name: second-listener
- drainType: MODIFY_ONLY
name: second-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 8083
defaultFilterChain:
filters:
@@ -90,15 +88,14 @@
resourceApiVersion: V3
routeConfigName: third-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8083
useRemoteAddress: true
name: third-listener
- drainType: MODIFY_ONLY
name: third-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 8084
defaultFilterChain:
filters:
@@ -123,9 +120,8 @@
resourceApiVersion: V3
routeConfigName: fourth-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-8084
useRemoteAddress: true
name: fourth-listener
- drainType: MODIFY_ONLY
name: fourth-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/health-check.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/health-check.clusters.yaml
index b789b876c3c..db58cac6601 100644
--- a/internal/xds/translator/testdata/out/xds-ir/health-check.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/health-check.clusters.yaml
@@ -4,7 +4,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
@@ -25,6 +25,7 @@
interval: 3s
timeout: 0.500s
unhealthyThreshold: 3
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
outlierDetection:
@@ -42,7 +43,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
@@ -61,6 +62,7 @@
interval: 5s
timeout: 1s
unhealthyThreshold: 3
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
outlierDetection:
@@ -78,7 +80,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
@@ -94,6 +96,7 @@
text: "70696e67"
timeout: 1s
unhealthyThreshold: 3
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
outlierDetection:
@@ -111,7 +114,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
@@ -127,6 +130,7 @@
binary: cGluZw==
timeout: 1s
unhealthyThreshold: 3
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fourth-route-dest
outlierDetection:
@@ -139,3 +143,27 @@
splitExternalLocalOriginErrors: true
perConnectionBufferLimitBytes: 32768
type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: fifth-route-dest
+ healthChecks:
+ - grpcHealthCheck:
+ serviceName: my-service
+ healthyThreshold: 3
+ interval: 5s
+ timeout: 1s
+ unhealthyThreshold: 3
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: fifth-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/health-check.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/health-check.endpoints.yaml
index f185af17da7..b93d9b43bde 100644
--- a/internal/xds/translator/testdata/out/xds-ir/health-check.endpoints.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/health-check.endpoints.yaml
@@ -46,3 +46,15 @@
loadBalancingWeight: 1
locality:
region: fourth-route-dest/backend/0
+- clusterName: fifth-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: fifth-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/health-check.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/health-check.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/health-check.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/health-check.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/health-check.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/health-check.routes.yaml
index de4249178e4..2f5c4977b24 100644
--- a/internal/xds/translator/testdata/out/xds-ir/health-check.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/health-check.routes.yaml
@@ -33,3 +33,10 @@
cluster: fourth-route-dest
upgradeConfigs:
- upgradeType: websocket
+ - match:
+ prefix: /
+ name: fifth-route
+ route:
+ cluster: fifth-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.clusters.yaml
new file mode 100644
index 00000000000..f015e69fceb
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.clusters.yaml
@@ -0,0 +1,44 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: first-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ httpProtocolOptions:
+ headerKeyFormat:
+ statefulFormatter:
+ name: preserve_case
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.header_formatters.preserve_case.v3.PreserveCaseFormatterConfig
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: second-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.endpoints.yaml
new file mode 100644
index 00000000000..28a57caf3b5
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.endpoints.yaml
@@ -0,0 +1,24 @@
+- clusterName: first-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: first-route-dest/backend/0
+- clusterName: second-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.5
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.listeners.yaml
new file mode 100644
index 00000000000..73dcc99a8b9
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.listeners.yaml
@@ -0,0 +1,106 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ httpProtocolOptions:
+ headerKeyFormat:
+ statefulFormatter:
+ name: preserve_case
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.header_formatters.preserve_case.v3.PreserveCaseFormatterConfig
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: first-listener
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10081
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ earlyHeaderMutationExtensions:
+ - name: envoy.http.early_header_mutation.header_mutation
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.early_header_mutation.header_mutation.v3.HeaderMutation
+ mutations:
+ - append:
+ header:
+ key: some-header
+ value: some-value1
+ - append:
+ header:
+ key: some-header
+ value: some-value2
+ - append:
+ header:
+ key: some-header-2
+ value: some-value
+ - append:
+ appendAction: OVERWRITE_IF_EXISTS_OR_ADD
+ header:
+ key: some-header3
+ value: some-value
+ - append:
+ appendAction: OVERWRITE_IF_EXISTS_OR_ADD
+ header:
+ key: some-header4
+ value: some-value
+ - append:
+ appendAction: OVERWRITE_IF_EXISTS_OR_ADD
+ header:
+ key: empty-header
+ keepEmptyValue: true
+ - remove: some-header5
+ - remove: some-header6
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ normalizePath: true
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: second-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10081
+ useRemoteAddress: true
+ name: second-listener
+ name: second-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.routes.yaml
new file mode 100644
index 00000000000..ff93cfff360
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.routes.yaml
@@ -0,0 +1,28 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ prefix: /
+ name: first-route
+ route:
+ cluster: first-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+- ignorePortInHostMatching: true
+ name: second-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: second-listener/*
+ routes:
+ - match:
+ prefix: /
+ name: second-route
+ route:
+ cluster: second-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.clusters.yaml
index e9ea29c138f..d825e6d3757 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
trackClusterStats:
perEndpointStats: true
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.listeners.yaml
index 7400b59665a..8b810de954d 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: listener-enable-endpoint-stats
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: listener-enable-endpoint-stats
- drainType: MODIFY_ONLY
name: listener-enable-endpoint-stats
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-health-check.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-health-check.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-health-check.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-health-check.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-health-check.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-health-check.listeners.yaml
index 048ff7cd4a5..1548f88fd66 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-health-check.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-health-check.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -35,9 +35,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml
index 5de1d1cce34..b532b46bdb2 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml
@@ -4,20 +4,22 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-1/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
useDownstreamProtocolConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
httpProtocolOptions: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.listeners.yaml
index c5665623154..09426a31773 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.listeners.yaml
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-1/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway/gateway-1/http
- drainType: MODIFY_ONLY
name: envoy-gateway/gateway-1/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.clusters.yaml
new file mode 100644
index 00000000000..5362244f7bf
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.clusters.yaml
@@ -0,0 +1,19 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: first-route-dest
+ perConnectionBufferLimitBytes: 32768
+ trackClusterStats:
+ requestResponseSizes: true
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.endpoints.yaml
new file mode 100644
index 00000000000..3b3f2d09076
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: first-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: first-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.listeners.yaml
new file mode 100644
index 00000000000..ac62b3d7a0b
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.listeners.yaml
@@ -0,0 +1,34 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: listener-enable-req-resp-sizes-stats
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: listener-enable-req-resp-sizes-stats
+ name: listener-enable-req-resp-sizes-stats
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.routes.yaml
new file mode 100644
index 00000000000..63cbc847197
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-req-resp-sizes-stats.routes.yaml
@@ -0,0 +1,14 @@
+- ignorePortInHostMatching: true
+ name: listener-enable-req-resp-sizes-stats
+ virtualHosts:
+ - domains:
+ - '*'
+ name: listener-enable-req-resp-sizes-stats/*
+ routes:
+ - match:
+ prefix: /
+ name: first-route
+ route:
+ cluster: first-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.clusters.yaml
index f0ea3b32320..df0e6b954a0 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: direct-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.routes.yaml
index b214e8b05a3..d4a7fa5ae20 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-direct-response.routes.yaml
@@ -6,6 +6,8 @@
name: first-listener/*
routes:
- directResponse:
+ body:
+ inlineString: 'Unknown custom filter type: UnsupportedType'
status: 500
match:
prefix: /
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-dns-cluster.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-dns-cluster.clusters.yaml
index 876e1084c87..07757e5fded 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-dns-cluster.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-dns-cluster.clusters.yaml
@@ -4,7 +4,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -27,7 +27,6 @@
locality:
region: first-route-dest/backend/0
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-dns-cluster.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-dns-cluster.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-dns-cluster.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-dns-cluster.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-mirror.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-mirror.clusters.yaml
index 53d1f9a7c1a..ce54d3a35d3 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-mirror.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-mirror.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-mirror.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-mirror.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-mirror.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-mirror.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-matches.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-matches.clusters.yaml
index 0322cbb616d..b70cda2ec59 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-matches.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-matches.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,15 +55,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fourth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -72,15 +72,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fifth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fifth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -89,15 +89,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: sixth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: sixth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -106,14 +106,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: seventh-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: seventh-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-matches.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-matches.listeners.yaml
index 67922c7444f..c3fb113017a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-matches.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-matches.listeners.yaml
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-mirrors.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-mirrors.clusters.yaml
index 046021604df..6ca132c714d 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-mirrors.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-mirrors.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: mirror-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: mirror-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,14 +38,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: mirror-route-dest1
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: mirror-route-dest1
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-mirrors.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-mirrors.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-mirrors.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-multiple-mirrors.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-partial-invalid.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-partial-invalid.clusters.yaml
index 61496817710..5c4d68ac903 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-partial-invalid.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-partial-invalid.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: valid-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: valid-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-partial-invalid.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-partial-invalid.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-partial-invalid.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-partial-invalid.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-redirect.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-redirect.clusters.yaml
index b435363bef7..2410099664d 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-redirect.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-redirect.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: redirect-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: redirect-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-redirect.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-redirect.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-redirect.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-redirect.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-regex.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-regex.clusters.yaml
index 0f75e67e278..058b9ac85b4 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-regex.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-regex.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: regex-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: regex-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-regex.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-regex.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-regex.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-regex.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.clusters.yaml
index 2adb8e01e4d..b43604253d1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: request-header-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: request-header-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.routes.yaml
index f91a70cb2ee..1f2c6be4057 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.routes.yaml
@@ -9,6 +9,12 @@
prefix: /
name: request-header-route
requestHeadersToAdd:
+ - header:
+ key: some-header-multi-value
+ value: some-value
+ - header:
+ key: some-header-multi-value
+ value: some-additional-value
- header:
key: some-header
value: some-value
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-headers.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-headers.clusters.yaml
index ca020e482fe..4d2ccc10e64 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-headers.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-headers.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: response-header-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: response-header-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-headers.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-headers.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-headers.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-headers.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-remove-headers.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-remove-headers.clusters.yaml
index ca020e482fe..4d2ccc10e64 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-remove-headers.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-remove-headers.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: response-header-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: response-header-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-remove-headers.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-remove-headers.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-remove-headers.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-response-add-remove-headers.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-response-remove-headers.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-response-remove-headers.clusters.yaml
index ca020e482fe..4d2ccc10e64 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-response-remove-headers.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-response-remove-headers.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: response-header-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: response-header-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-response-remove-headers.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-response-remove-headers.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-response-remove-headers.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-response-remove-headers.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-root-path-url-prefix.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-root-path-url-prefix.clusters.yaml
index 027db39fb29..ce7e7e58572 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-root-path-url-prefix.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-root-path-url-prefix.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: rewrite-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: rewrite-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-root-path-url-prefix.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-root-path-url-prefix.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-root-path-url-prefix.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-root-path-url-prefix.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.clusters.yaml
new file mode 100644
index 00000000000..ce7e7e58572
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.clusters.yaml
@@ -0,0 +1,17 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: rewrite-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: rewrite-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.endpoints.yaml
new file mode 100644
index 00000000000..256dda09089
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: rewrite-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: rewrite-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.listeners.yaml
new file mode 100644
index 00000000000..80ae84fd104
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.listeners.yaml
@@ -0,0 +1,34 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: first-listener
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.routes.yaml
new file mode 100644
index 00000000000..84bc70f04bd
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-sufixx-with-slash-url-prefix.routes.yaml
@@ -0,0 +1,19 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - gateway.envoyproxy.io
+ name: first-listener/gateway_envoyproxy_io
+ routes:
+ - match:
+ headers:
+ - name: :authority
+ stringMatch:
+ exact: gateway.envoyproxy.io
+ pathSeparatedPrefix: /origin
+ name: rewrite-route
+ route:
+ cluster: rewrite-route-dest
+ prefixRewrite: /rewrite
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-fullpath.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-fullpath.clusters.yaml
index 3a2b7308d8e..171998c0b51 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-fullpath.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-fullpath.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: rewrite-route
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: rewrite-route
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-fullpath.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-fullpath.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-fullpath.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-fullpath.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.clusters.yaml
index 027db39fb29..ce7e7e58572 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: rewrite-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: rewrite-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.routes.yaml
index 680a67404ee..a3e1e29e821 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-host.routes.yaml
@@ -19,3 +19,31 @@
prefixRewrite: /rewrite
upgradeConfigs:
- upgradeType: websocket
+ - match:
+ headers:
+ - name: :authority
+ stringMatch:
+ exact: gateway.envoyproxy.io
+ pathSeparatedPrefix: /host-header
+ name: rewrite-host-header
+ route:
+ appendXForwardedHost: true
+ cluster: rewrite-route-dest
+ hostRewriteHeader: foo
+ prefixRewrite: /rewrite
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ headers:
+ - name: :authority
+ stringMatch:
+ exact: gateway.envoyproxy.io
+ pathSeparatedPrefix: /host-backend
+ name: rewrite-host-backend
+ route:
+ appendXForwardedHost: true
+ autoHostRewrite: true
+ cluster: rewrite-route-dest
+ prefixRewrite: /rewrite
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-prefix.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-prefix.clusters.yaml
index 027db39fb29..ce7e7e58572 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-prefix.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-prefix.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: rewrite-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: rewrite-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-prefix.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-prefix.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-prefix.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-prefix.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.clusters.yaml
new file mode 100644
index 00000000000..171998c0b51
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.clusters.yaml
@@ -0,0 +1,17 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: rewrite-route
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: rewrite-route
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.endpoints.yaml
new file mode 100644
index 00000000000..ca1ef21c989
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: rewrite-route
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: rewrite-route/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.listeners.yaml
new file mode 100644
index 00000000000..80ae84fd104
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.listeners.yaml
@@ -0,0 +1,34 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: first-listener
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.routes.yaml
new file mode 100644
index 00000000000..20d4e99ef68
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-rewrite-url-regex.routes.yaml
@@ -0,0 +1,18 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - gateway.envoyproxy.io
+ name: first-listener/gateway_envoyproxy_io
+ routes:
+ - match:
+ pathSeparatedPrefix: /origin
+ name: rewrite-route
+ route:
+ cluster: rewrite-route
+ regexRewrite:
+ pattern:
+ regex: ^/service/([^/]+)(/.*)$
+ substitution: \2/instance/\1
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.clusters.yaml
new file mode 100644
index 00000000000..058b9ac85b4
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.clusters.yaml
@@ -0,0 +1,17 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: regex-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: regex-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.endpoints.yaml
new file mode 100644
index 00000000000..b36ee450059
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: regex-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: regex-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml
new file mode 100644
index 00000000000..ed3356f4a2d
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml
@@ -0,0 +1,79 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.stateful_session/header-based-session-persistence-route
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
+ sessionState:
+ name: envoy.http.stateful_session.header
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.stateful_session.header.v3.HeaderBasedSessionState
+ name: session-header
+ - disabled: true
+ name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-regex
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
+ sessionState:
+ name: envoy.http.stateful_session.cookie
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
+ cookie:
+ name: session-header
+ path: /v1
+ ttl: 3600s
+ - disabled: true
+ name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-prefix
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
+ sessionState:
+ name: envoy.http.stateful_session.cookie
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
+ cookie:
+ name: session-header
+ path: /v2/
+ ttl: 3600s
+ - disabled: true
+ name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-exact
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
+ sessionState:
+ name: envoy.http.stateful_session.cookie
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
+ cookie:
+ name: session-cookie
+ path: /v3/user
+ ttl: 3600s
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: first-listener
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml
new file mode 100644
index 00000000000..c5450601be4
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml
@@ -0,0 +1,53 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ safeRegex:
+ regex: /v1/.*
+ name: header-based-session-persistence-route
+ route:
+ cluster: regex-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.stateful_session/header-based-session-persistence-route:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - match:
+ safeRegex:
+ regex: /v1/.*/hoge
+ name: cookie-based-session-persistence-route-regex
+ route:
+ cluster: regex-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.stateful_session/cookie-based-session-persistence-route-regex:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - match:
+ pathSeparatedPrefix: /v2
+ name: cookie-based-session-persistence-route-prefix
+ route:
+ cluster: regex-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.stateful_session/cookie-based-session-persistence-route-prefix:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - match:
+ path: /v3/user
+ name: cookie-based-session-persistence-route-exact
+ route:
+ cluster: regex-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.stateful_session/cookie-based-session-persistence-route-exact:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.clusters.yaml
index a89644e62d9..b70cda2ec59 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,14 +38,82 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: fourth-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: fifth-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: fifth-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: sixth-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: sixth-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: seventh-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: seventh-route-dest
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.endpoints.yaml
index 42a346c4041..59669a901a0 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.endpoints.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.endpoints.yaml
@@ -34,3 +34,51 @@
loadBalancingWeight: 1
locality:
region: third-route-dest/backend/0
+- clusterName: fourth-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50002
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: fourth-route-dest/backend/0
+- clusterName: fifth-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50002
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: fifth-route-dest/backend/0
+- clusterName: sixth-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50002
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: sixth-route-dest/backend/0
+- clusterName: seventh-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50002
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: seventh-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.routes.yaml
index 23d2bf4b701..1c335ad621e 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-timeout.routes.yaml
@@ -36,3 +36,39 @@
timeout: 0s
upgradeConfigs:
- upgradeType: websocket
+ - match:
+ prefix: /
+ name: forth-route
+ route:
+ cluster: fourth-route-dest
+ idleTimeout: 3600s
+ timeout: 10s
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ prefix: /
+ name: fifth-route
+ route:
+ cluster: fifth-route-dest
+ idleTimeout: 3600s
+ timeout: 10s
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ prefix: /
+ name: sixth-route
+ route:
+ cluster: sixth-route-dest
+ idleTimeout: 0s
+ timeout: 0s
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ prefix: /
+ name: seventh-route
+ route:
+ cluster: seventh-route-dest
+ idleTimeout: 0s
+ timeout: 0s
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-uds-ip.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-with-filters.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-with-filters.clusters.yaml
index d65e267ad7d..ba595752d94 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-with-filters.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-with-filters.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-with-filters.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-with-filters.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-with-filters.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend-with-filters.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.routes.yaml
index 6b53d359a22..235dea42729 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-invalid-backend.routes.yaml
@@ -16,3 +16,5 @@
clusters:
- name: invalid-backend-cluster
weight: 1
+ - name: first-route-dest
+ weight: 1
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-clientcert.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-clientcert.clusters.yaml
index 6d69b493981..8d1fa95bcc6 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-clientcert.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-clientcert.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/envoy-gateway/httproute-btls/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/envoy-gateway/httproute-btls/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
transportSocketMatches:
- match:
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-clientcert.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-clientcert.listeners.yaml
index ff5431da747..657d2b42a82 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-clientcert.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-clientcert.listeners.yaml
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-btls/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway/gateway-btls/http
- drainType: MODIFY_ONLY
name: envoy-gateway/gateway-btls/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-metadata.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-metadata.clusters.yaml
index d65e267ad7d..ba595752d94 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-metadata.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-metadata.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-metadata.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-metadata.listeners.yaml
index 67922c7444f..c3fb113017a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-metadata.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-metadata.listeners.yaml
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-stripped-host-port.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-stripped-host-port.clusters.yaml
index 2c908f7ef69..83e21e58286 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-stripped-host-port.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-stripped-host-port.clusters.yaml
@@ -8,6 +8,5 @@
resourceApiVersion: V3
serviceName: first-route
name: first-route
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tls-system-truststore.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tls-system-truststore.clusters.yaml
index 573625b4671..29d3e697c22 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tls-system-truststore.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tls-system-truststore.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/envoy-gateway/httproute-btls/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/envoy-gateway/httproute-btls/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
transportSocketMatches:
- match:
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tls-system-truststore.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tls-system-truststore.listeners.yaml
index ff5431da747..657d2b42a82 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tls-system-truststore.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tls-system-truststore.listeners.yaml
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-btls/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway/gateway-btls/http
- drainType: MODIFY_ONLY
name: envoy-gateway/gateway-btls/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle-multiple-certs.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle-multiple-certs.clusters.yaml
index ccfa16dbd99..3061088f3eb 100755
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle-multiple-certs.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle-multiple-certs.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/envoy-gateway/httproute-btls/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/envoy-gateway/httproute-btls/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
transportSocketMatches:
- match:
@@ -62,15 +62,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/envoy-gateway/httproute-btls-2/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/envoy-gateway/httproute-btls-2/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
transportSocket:
name: envoy.transport_sockets.upstream_proxy_protocol
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle-multiple-certs.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle-multiple-certs.listeners.yaml
index b227eccb031..5a43997887d 100755
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle-multiple-certs.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle-multiple-certs.listeners.yaml
@@ -27,10 +27,9 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-btls/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway/gateway-btls/http
- drainType: MODIFY_ONLY
name: envoy-gateway/gateway-btls/http
perConnectionBufferLimitBytes: 32768
- address:
@@ -62,9 +61,8 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-btls-2/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10081
useRemoteAddress: true
name: envoy-gateway/gateway-btls-2/http
- drainType: MODIFY_ONLY
name: envoy-gateway/gateway-btls-2/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle.clusters.yaml
index f368f4c94d0..0ba4829c936 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/envoy-gateway/httproute-btls/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/envoy-gateway/httproute-btls/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
transportSocketMatches:
- match:
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle.listeners.yaml
index ff5431da747..657d2b42a82 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-with-tlsbundle.listeners.yaml
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-btls/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway/gateway-btls/http
- drainType: MODIFY_ONLY
name: envoy-gateway/gateway-btls/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http1-preserve-case.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http1-preserve-case.clusters.yaml
index 1489e95f6fd..d9d1f8189a5 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http1-preserve-case.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http1-preserve-case.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
@@ -31,15 +31,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
diff --git a/internal/xds/translator/testdata/out/xds-ir/http1-preserve-case.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http1-preserve-case.listeners.yaml
index 60f8750a290..8cebad7030e 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http1-preserve-case.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http1-preserve-case.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -33,15 +33,14 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
defaultFilterChain:
filters:
@@ -75,9 +74,8 @@
resourceApiVersion: V3
routeConfigName: second-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10081
useRemoteAddress: true
name: second-listener
- drainType: MODIFY_ONLY
name: second-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http1-trailers.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http1-trailers.clusters.yaml
index 8c3dd7a549c..0bb16c7f4db 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http1-trailers.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http1-trailers.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
diff --git a/internal/xds/translator/testdata/out/xds-ir/http1-trailers.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http1-trailers.listeners.yaml
index d6cb3b5d2c6..eb0e689ae97 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http1-trailers.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http1-trailers.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -29,9 +29,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http10.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http10.clusters.yaml
index 2cb022cfad0..389a66ffb3a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http10.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http10.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
diff --git a/internal/xds/translator/testdata/out/xds-ir/http10.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http10.listeners.yaml
index 5eded6a4653..61260cb9507 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http10.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http10.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -30,9 +30,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml
index 6086cfbb86f..5db664bf32a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml
@@ -4,19 +4,91 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 524288000
+ initialStreamWindowSize: 1048576
+ maxConcurrentStreams: 200
+ overrideStreamErrorOnInvalidHttpMessage: true
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: second-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: third-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ useDownstreamProtocolConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 524288000
+ initialStreamWindowSize: 1048576
+ maxConcurrentStreams: 200
+ overrideStreamErrorOnInvalidHttpMessage: false
+ httpProtocolOptions: {}
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: fourth-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml
index 3b3f2d09076..f185af17da7 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml
@@ -10,3 +10,39 @@
loadBalancingWeight: 1
locality:
region: first-route-dest/backend/0
+- clusterName: second-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
+- clusterName: third-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: third-route-dest/backend/0
+- clusterName: fourth-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: fourth-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.listeners.yaml
index f7ab1ba34a0..460fcf1fc0b 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http2-route.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -35,9 +35,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml
index a32852fcd88..4fdedfabf67 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml
@@ -20,3 +20,24 @@
cluster: first-route-dest
upgradeConfigs:
- upgradeType: websocket
+ - match:
+ path: bar/foo
+ name: second-route
+ route:
+ cluster: second-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ path: bar/bar
+ name: third-route-use-client
+ route:
+ cluster: third-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ path: foo/foo
+ name: fourth-route-not-http2
+ route:
+ cluster: fourth-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/http2.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http2.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100755
--- a/internal/xds/translator/testdata/out/xds-ir/http2.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http2.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http2.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http2.listeners.yaml
index 1d2cc2574ae..0ac436eeb75 100755
--- a/internal/xds/translator/testdata/out/xds-ir/http2.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http2.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http3.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http3.clusters.yaml
index 9714612e3de..c24d059eeaa 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http3.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http3.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-1/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http3.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http3.listeners.yaml
index fdfdb3bbdf5..49a651da85e 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http3.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http3.listeners.yaml
@@ -31,7 +31,7 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-1/tls
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10443
useRemoteAddress: true
name: envoy-gateway/gateway-1/tls
transportSocket:
@@ -47,6 +47,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
name: envoy-gateway/gateway-1/tls-quic
udpListenerConfig:
downstreamSocketConfig: {}
@@ -55,7 +57,6 @@
socketAddress:
address: 0.0.0.0
portValue: 10443
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -81,7 +82,7 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-1/tls
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10443
useRemoteAddress: true
name: envoy-gateway/gateway-1/tls
transportSocket:
@@ -97,5 +98,7 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
name: envoy-gateway/gateway-1/tls
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.clusters.yaml
new file mode 100644
index 00000000000..2471dd8cb4f
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.clusters.yaml
@@ -0,0 +1,16 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: first-route-dest
+ lbPolicy: LEAST_REQUEST
+ name: first-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.endpoints.yaml
new file mode 100644
index 00000000000..9a6f5a46c91
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.endpoints.yaml
@@ -0,0 +1,24 @@
+- clusterName: first-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: first-route-dest/backend/0
+- clusterName: second-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 4.5.6.7
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.envoypatchpolicies.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.envoypatchpolicies.yaml
new file mode 100644
index 00000000000..9508dd3e7b3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.envoypatchpolicies.yaml
@@ -0,0 +1,16 @@
+- name: first-policy
+ namespace: default
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: foobar
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Patches have been successfully applied.
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ controllerName: ""
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.listeners.yaml
new file mode 100644
index 00000000000..51c022c26f3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.listeners.yaml
@@ -0,0 +1,52 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ drainType: MODIFY_ONLY
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: https-10080
+ useRemoteAddress: true
+ name: first-listener
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
+ commonTlsContext:
+ alpnProtocols:
+ - h2
+ - http/1.1
+ tlsCertificateSdsSecretConfigs:
+ - name: secret-1
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ - name: secret-2
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.routes.yaml
new file mode 100644
index 00000000000..4a412b3576a
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.routes.yaml
@@ -0,0 +1,18 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ headers:
+ - name: user
+ stringMatch:
+ exact: jason
+ prefix: /
+ name: first-route
+ route:
+ cluster: first-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.secrets.yaml
new file mode 100644
index 00000000000..ad88ffe43cd
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.secrets.yaml
@@ -0,0 +1,12 @@
+- name: secret-1
+ tlsCertificate:
+ certificateChain:
+ inlineBytes: Y2VydC1kYXRh
+ privateKey:
+ inlineBytes: a2V5LWRhdGE=
+- name: secret-2
+ tlsCertificate:
+ certificateChain:
+ inlineBytes: Y2VydC1kYXRh
+ privateKey:
+ inlineBytes: a2V5LWRhdGE=
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.clusters.yaml
index d53a7a1b2ce..2471dd8cb4f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-without-value.clusters.yaml
@@ -12,6 +12,5 @@
serviceName: first-route-dest
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-invalid-patch.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-invalid-patch.clusters.yaml
index d53a7a1b2ce..2471dd8cb4f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-invalid-patch.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-invalid-patch.clusters.yaml
@@ -12,6 +12,5 @@
serviceName: first-route-dest
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-missing-resource.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-missing-resource.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-missing-resource.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-missing-resource.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-missing-resource.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-missing-resource.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-missing-resource.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-missing-resource.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.clusters.yaml
index d53a7a1b2ce..2471dd8cb4f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-move-op-with-value.clusters.yaml
@@ -12,6 +12,5 @@
serviceName: first-route-dest
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.clusters.yaml
new file mode 100644
index 00000000000..20e66b92760
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.clusters.yaml
@@ -0,0 +1,47 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: first-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: second-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- connectTimeout: 10s
+ http2ProtocolOptions: {}
+ loadAssignment:
+ clusterName: rate-limit-cluster
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: ratelimit.svc.cluster.local
+ portValue: 8081
+ name: rate-limit-cluster
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.endpoints.yaml
new file mode 100644
index 00000000000..131cd47c730
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.endpoints.yaml
@@ -0,0 +1,32 @@
+- clusterName: first-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 50
+ locality:
+ region: first-route-dest/backend/0
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 50
+- clusterName: second-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 4.5.6.7
+ portValue: 60000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.envoypatchpolicies.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.envoypatchpolicies.yaml
new file mode 100644
index 00000000000..9508dd3e7b3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.envoypatchpolicies.yaml
@@ -0,0 +1,16 @@
+- name: first-policy
+ namespace: default
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: foobar
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Patches have been successfully applied.
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ controllerName: ""
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.listeners.yaml
new file mode 100644
index 00000000000..8aaea6d5fd4
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.listeners.yaml
@@ -0,0 +1,65 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.ratelimit
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
+ domain: eg-ratelimit
+ failureModeDeny: true
+ rateLimitService:
+ grpcService:
+ envoyGrpc:
+ clusterName: rate-limit-cluster
+ transportApiVersion: V3
+ timeout: 1s
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ preserveExternalRequestId: true
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: https-10080
+ useRemoteAddress: true
+ name: first-listener
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
+ commonTlsContext:
+ alpnProtocols:
+ - h2
+ - http/1.1
+ tlsCertificateSdsSecretConfigs:
+ - name: secret-1
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ - name: secret-2
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.routes.yaml
new file mode 100644
index 00000000000..a7273c7a1b8
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.routes.yaml
@@ -0,0 +1,36 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ rateLimits:
+ - actions:
+ - remoteAddress: {}
+ routes:
+ - match:
+ headers:
+ - name: user
+ stringMatch:
+ exact: jason
+ prefix: /
+ name: first-route
+ route:
+ cluster: first-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ headers:
+ - name: user
+ stringMatch:
+ exact: james
+ - name: country
+ stringMatch:
+ exact: US
+ prefix: /
+ name: second-route
+ route:
+ cluster: second-route-dest
+ upgradeConfigs:
+ - connectConfig: {}
+ upgradeType: CONNECT
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.secrets.yaml
new file mode 100644
index 00000000000..d1c4b32fd5f
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.secrets.yaml
@@ -0,0 +1,16 @@
+- name: secret-1
+ tlsCertificate:
+ certificateChain:
+ inlineBytes: a2V5LWRhdGE=
+ privateKey:
+ inlineBytes: a2V5LWRhdGE=
+- name: secret-2
+ tlsCertificate:
+ certificateChain:
+ inlineBytes: Y2VydC1kYXRh
+ privateKey:
+ inlineBytes: a2V5LWRhdGE=
+- name: test_secret
+ tlsCertificate:
+ certificateChain:
+ inlineBytes: Y2VydC1kYXRh
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch.clusters.yaml
index b6e4ed1ae7d..cfa4f05980c 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jsonpatch.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- connectTimeout: 10s
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch.listeners.yaml
index dbc5b4b25a2..8aaea6d5fd4 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jsonpatch.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -40,7 +39,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10080
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -60,5 +59,7 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-custom-extractor.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-custom-extractor.clusters.yaml
index 8ede70cf99a..0f65c235f33 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-custom-extractor.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-custom-extractor.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,7 +21,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -38,7 +38,6 @@
locality:
region: localhost_443/backend/0
name: localhost_443
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-custom-extractor.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-custom-extractor.listeners.yaml
index 1f89b694bb6..d5b2dfa8ee2 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-custom-extractor.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-custom-extractor.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -30,7 +30,10 @@
fromParams:
- token
issuer: https://www.example.com
- payloadInMetadata: https://www.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -38,7 +41,6 @@
cluster: localhost_443
timeout: 10s
uri: https://localhost/jwt/public-key/jwks.json
- retryPolicy: {}
requirementMap:
first-route:
providerName: first-route/example
@@ -55,9 +57,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-multi-provider.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-multi-provider.clusters.yaml
index 9de709310e6..b5801be5702 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-multi-provider.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-multi-provider.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-www.test.com-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-www.test.com-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-www.test.com-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-www.test.com-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,7 +38,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -55,7 +55,6 @@
locality:
region: localhost_80/backend/0
name: localhost_80
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
type: STRICT_DNS
@@ -65,15 +64,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: "192_168_1_250_8080"
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: "192_168_1_250_8080"
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
transportSocket:
name: envoy.transport_sockets.tls
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-multi-provider.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-multi-provider.listeners.yaml
index 5803c41968c..95c52f2a86a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-multi-provider.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-multi-provider.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -26,7 +26,10 @@
headerName: one-route-example-key1
forward: true
issuer: https://www.example.com
- payloadInMetadata: https://www.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -34,7 +37,6 @@
cluster: localhost_80
timeout: 10s
uri: http://localhost/jwt/public-key/jwks.json
- retryPolicy: {}
first-route-www.test.com/example2:
audiences:
- one.foo.com
@@ -47,7 +49,10 @@
clearRouteCache: true
forward: true
issuer: https://www.two.example.com
- payloadInMetadata: https://www.two.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example2
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -55,7 +60,6 @@
cluster: "192_168_1_250_8080"
timeout: 10s
uri: https://192.168.1.250:8080/jwt/public-key/jwks.json
- retryPolicy: {}
second-route-www.test.com/example:
audiences:
- foo.com
@@ -64,7 +68,10 @@
headerName: second-route-example-key1
forward: true
issuer: https://www.example.com
- payloadInMetadata: https://www.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -72,14 +79,16 @@
cluster: localhost_80
timeout: 10s
uri: http://localhost/jwt/public-key/jwks.json
- retryPolicy: {}
second-route-www.test.com/example2:
audiences:
- one.foo.com
- two.foo.com
forward: true
issuer: https://www.two.example.com
- payloadInMetadata: https://www.two.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example2
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -87,7 +96,6 @@
cluster: "192_168_1_250_8080"
timeout: 10s
uri: https://192.168.1.250:8080/jwt/public-key/jwks.json
- retryPolicy: {}
requirementMap:
first-route-www.test.com:
requiresAny:
@@ -112,9 +120,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-single-provider.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-single-provider.clusters.yaml
index 8d7b2d37ca0..ead2234d08f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-single-provider.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-single-provider.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,7 +38,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -55,7 +55,6 @@
locality:
region: localhost_443/backend/0
name: localhost_443
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-single-provider.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-single-provider.listeners.yaml
index 367f5fa529f..e715f2945c4 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-single-provider.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-multi-route-single-provider.listeners.yaml
@@ -13,7 +13,7 @@
path: /dev/stdout
address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -48,7 +48,10 @@
headerName: first-route-key
forward: true
issuer: https://www.example.com
- payloadInMetadata: https://www.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -56,13 +59,15 @@
cluster: localhost_443
timeout: 10s
uri: https://localhost/jwt/public-key/jwks.json
- retryPolicy: {}
second-route/example:
audiences:
- foo.com
forward: true
issuer: https://www.example.com
- payloadInMetadata: https://www.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -70,7 +75,6 @@
cluster: localhost_443
timeout: 10s
uri: https://localhost/jwt/public-key/jwks.json
- retryPolicy: {}
requirementMap:
first-route:
providerName: first-route/example
@@ -89,9 +93,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-optional.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.clusters.yaml
index 8ede70cf99a..0f65c235f33 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-optional.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,7 +21,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -38,7 +38,6 @@
locality:
region: localhost_443/backend/0
name: localhost_443
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-optional.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.listeners.yaml
index a4303573e3e..4a6a9a06315 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-optional.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -30,7 +30,10 @@
fromParams:
- token
issuer: https://www.example.com
- payloadInMetadata: https://www.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -38,7 +41,6 @@
cluster: localhost_443
timeout: 10s
uri: https://localhost/jwt/public-key/jwks.json
- retryPolicy: {}
requirementMap:
first-route:
requiresAny:
@@ -58,9 +60,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml
index d4e9db34e33..c68eced8a40 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,15 +55,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: "192_168_1_250_443"
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: "192_168_1_250_443"
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
transportSocket:
name: envoy.transport_sockets.tls
@@ -81,7 +81,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -98,7 +98,6 @@
locality:
region: ratelimit_cluster/backend/0
name: ratelimit_cluster
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
@@ -119,4 +118,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.listeners.yaml
index 4e52213f3af..53af66649b7 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -23,7 +23,10 @@
- foo.com
forward: true
issuer: https://www.example.com
- payloadInMetadata: https://www.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -31,7 +34,6 @@
cluster: "192_168_1_250_443"
timeout: 10s
uri: https://192.168.1.250/jwt/public-key/jwks.json
- retryPolicy: {}
requirementMap:
first-route:
providerName: first-route/example
@@ -58,9 +60,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-single-route-single-match.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-single-route-single-match.clusters.yaml
index 8ede70cf99a..0f65c235f33 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-single-route-single-match.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-single-route-single-match.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,7 +21,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -38,7 +38,6 @@
locality:
region: localhost_443/backend/0
name: localhost_443
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-single-route-single-match.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-single-route-single-match.listeners.yaml
index b1ccf1a70cd..eb828bbc9d4 100644
--- a/internal/xds/translator/testdata/out/xds-ir/jwt-single-route-single-match.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/jwt-single-route-single-match.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -23,7 +23,10 @@
- foo.com
forward: true
issuer: https://www.example.com
- payloadInMetadata: https://www.example.com
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: example
remoteJwks:
asyncFetch: {}
cacheDuration: 300s
@@ -31,7 +34,6 @@
cluster: localhost_443
timeout: 10s
uri: https://localhost/jwt/public-key/jwks.json
- retryPolicy: {}
requirementMap:
first-route:
providerName: first-route/example
@@ -48,9 +50,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.clusters.yaml
index d65e267ad7d..d4e79e5ab04 100644
--- a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,48 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: tls-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: tls-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: tcp-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: tcp-route-dest
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.endpoints.yaml
index de95bf555b9..5b4fe89e58c 100644
--- a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.endpoints.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.endpoints.yaml
@@ -22,3 +22,27 @@
loadBalancingWeight: 1
locality:
region: second-route-dest/backend/0
+- clusterName: tls-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: tls-route-dest/backend/0
+- clusterName: tcp-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: tcp-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.listeners.yaml
index 66faa259661..079ca70cfd3 100644
--- a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,15 +27,14 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
defaultFilterChain:
filters:
@@ -43,7 +42,7 @@
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit
maxConnections: "5"
- statPrefix: http
+ statPrefix: http-10081
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
@@ -67,23 +66,52 @@
resourceApiVersion: V3
routeConfigName: second-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10081
useRemoteAddress: true
name: second-listener
- drainType: MODIFY_ONLY
name: second-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10082
- drainType: MODIFY_ONLY
+ filterChains:
+ - filterChainMatch:
+ serverNames:
+ - bar.com
+ filters:
+ - name: envoy.filters.network.connection_limit
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit
+ maxConnections: "3"
+ statPrefix: tls-passthrough-10082
+ - name: envoy.filters.network.tcp_proxy
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+ cluster: tls-route-dest
+ statPrefix: tls-passthrough-10082
+ listenerFilters:
+ - name: envoy.filters.listener.tls_inspector
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
name: third-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10083
- drainType: MODIFY_ONLY
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.connection_limit
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit
+ delay: 3s
+ maxConnections: "10"
+ statPrefix: tcp-10083
+ - name: envoy.filters.network.tcp_proxy
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+ cluster: tcp-route-dest
+ statPrefix: tcp-10083
name: fourth-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.clusters.yaml
index 454192ce491..fd2f5440287 100644
--- a/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tls-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tls-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.listeners.yaml
index d8ea3aaf802..89258f90704 100644
--- a/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -31,7 +30,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10080
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -51,6 +50,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
listenerFilters:
- name: envoy.filters.listener.proxy_protocol
typedConfig:
@@ -62,16 +63,15 @@
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tls-route-dest
- statPrefix: tcp
+ statPrefix: tcp-10081
name: tcp-route-dest
listenerFilters:
- name: envoy.filters.listener.proxy_protocol
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.clusters.yaml
index d65e267ad7d..d4e79e5ab04 100644
--- a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,48 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: tls-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: tls-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: tcp-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: tcp-route-dest
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.endpoints.yaml
index de95bf555b9..5b4fe89e58c 100644
--- a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.endpoints.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.endpoints.yaml
@@ -22,3 +22,27 @@
loadBalancingWeight: 1
locality:
region: second-route-dest/backend/0
+- clusterName: tls-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: tls-route-dest/backend/0
+- clusterName: tcp-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: tcp-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.listeners.yaml
index 610086b57ab..afcd96ff6b0 100644
--- a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,10 +27,9 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
socketOptions:
@@ -40,7 +39,7 @@
name: "9"
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
defaultFilterChain:
filters:
@@ -67,10 +66,9 @@
resourceApiVersion: V3
routeConfigName: second-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10081
useRemoteAddress: true
name: second-listener
- drainType: MODIFY_ONLY
name: second-listener
perConnectionBufferLimitBytes: 32768
socketOptions:
@@ -92,9 +90,22 @@
name: "5"
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10082
- drainType: MODIFY_ONLY
+ filterChains:
+ - filterChainMatch:
+ serverNames:
+ - bar.com
+ filters:
+ - name: envoy.filters.network.tcp_proxy
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+ cluster: tls-route-dest
+ statPrefix: tls-passthrough-10082
+ listenerFilters:
+ - name: envoy.filters.listener.tls_inspector
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
name: third-listener
perConnectionBufferLimitBytes: 32768
socketOptions:
@@ -104,9 +115,15 @@
name: "9"
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10083
- drainType: MODIFY_ONLY
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.tcp_proxy
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+ cluster: tcp-route-dest
+ statPrefix: tcp-10083
name: fourth-listener
perConnectionBufferLimitBytes: 32768
socketOptions:
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.clusters.yaml
new file mode 100644
index 00000000000..0764d46f0ed
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.clusters.yaml
@@ -0,0 +1,2 @@
+- name: EmptyCluster
+ type: STATIC
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.endpoints.yaml
new file mode 100644
index 00000000000..fe51488c706
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.endpoints.yaml
@@ -0,0 +1 @@
+[]
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.listeners.yaml
new file mode 100644
index 00000000000..6539e7588ec
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.listeners.yaml
@@ -0,0 +1,42 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10443
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.connection_limit
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit
+ delay: 10s
+ maxConnections: "3"
+ statPrefix: tcp-10443
+ - name: envoy.filters.network.tcp_proxy
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+ cluster: EmptyCluster
+ idleTimeout: 1200s
+ statPrefix: tcp-10443
+ name: EmptyCluster
+ listenerFilters:
+ - name: envoy.filters.listener.proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol
+ name: envoy-gateway/gateway-1/tls-1
+ perConnectionBufferLimitBytes: 50000000
+ socketOptions:
+ - description: socket option to enable tcp keep alive
+ intValue: "1"
+ level: "1"
+ name: "9"
+ - description: socket option for keep alive probes
+ intValue: "3"
+ level: "6"
+ name: "6"
+ - description: socket option for keep alive idle time
+ intValue: "1200"
+ level: "6"
+ name: "4"
+ - description: socket option for keep alive interval
+ intValue: "60"
+ level: "6"
+ name: "5"
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.routes.yaml
new file mode 100644
index 00000000000..fe51488c706
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-without-route.routes.yaml
@@ -0,0 +1 @@
+[]
diff --git a/internal/xds/translator/testdata/out/xds-ir/load-balancer.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/load-balancer.clusters.yaml
index 16792f24cb1..449ed38b574 100644
--- a/internal/xds/translator/testdata/out/xds-ir/load-balancer.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/load-balancer.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -20,15 +20,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: RANDOM
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -37,15 +37,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -54,15 +54,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: MAGLEV
name: fourth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -71,18 +71,18 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fifth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
leastRequestLbConfig:
slowStartConfig:
slowStartWindow: 60s
name: fifth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -91,14 +91,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: sixth-route-dest
+ ignoreHealthOnHostRemoval: true
name: sixth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
roundRobinLbConfig:
slowStartConfig:
@@ -110,15 +110,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: seventh-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: MAGLEV
name: seventh-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -127,17 +127,17 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: eighth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: MAGLEV
maglevLbConfig:
tableSize: "524287"
name: eighth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -146,15 +146,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: ninth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: MAGLEV
name: ninth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -163,14 +163,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tenth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: MAGLEV
name: tenth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/load-balancer.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/load-balancer.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/load-balancer.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/load-balancer.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/local-ratelimit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/local-ratelimit.clusters.yaml
index a89644e62d9..121c8aad8bb 100644
--- a/internal/xds/translator/testdata/out/xds-ir/local-ratelimit.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/local-ratelimit.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,14 +38,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/local-ratelimit.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/local-ratelimit.listeners.yaml
index 0f578bca015..aff3d89b5f5 100644
--- a/internal/xds/translator/testdata/out/xds-ir/local-ratelimit.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/local-ratelimit.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -31,9 +31,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/metrics-virtual-host.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/metrics-virtual-host.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/metrics-virtual-host.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/metrics-virtual-host.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/metrics-virtual-host.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/metrics-virtual-host.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/metrics-virtual-host.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/metrics-virtual-host.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.listeners.yaml
index f81185b04b4..65814a64bd0 100644
--- a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -28,7 +27,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10080
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -44,5 +43,7 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.clusters.yaml
index 2b9b567cf39..7e8ec0664db 100755
--- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-1/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-2/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: securitypolicy/default/policy-for-http-route-2/envoy-gateway/http-backend
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: securitypolicy/default/policy-for-http-route-2/envoy-gateway/http-backend
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,15 +55,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-3/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-3/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -72,7 +72,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -89,7 +89,6 @@
locality:
region: oauth_foo_com_443/backend/0
name: oauth_foo_com_443
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml
index 2242bb6a8a7..39bfe9f587b 100755
--- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml
@@ -55,7 +55,7 @@
resourceApiVersion: V3
routeConfigName: default/gateway-1/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: default/gateway-1/http
drainType: MODIFY_ONLY
@@ -122,6 +122,7 @@
idToken: IdToken-5F93C2E4
oauthExpires: OauthExpires-5F93C2E4
oauthHmac: OauthHMAC-5F93C2E4
+ oauthNonce: OauthNonce-5F93C2E4
refreshToken: RefreshToken-5F93C2E4
hmacSecret:
name: oauth2/hmac_secret/securitypolicy/default/policy-for-gateway-2
@@ -159,9 +160,8 @@
resourceApiVersion: V3
routeConfigName: default/gateway-1/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: default/gateway-1/http
- drainType: MODIFY_ONLY
name: default/gateway-1/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port.clusters.yaml
index ce7f4361a40..cbe74c802d2 100644
--- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,15 +55,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fourth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -72,15 +72,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -89,14 +89,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tls-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tls-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port.listeners.yaml
index 181bb255cdb..5c84e82a4ac 100644
--- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,10 +27,9 @@
resourceApiVersion: V3
routeConfigName: third-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: third-listener
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -59,7 +58,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10080
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -75,6 +74,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
- filterChainMatch:
serverNames:
- foo.net
@@ -102,7 +103,7 @@
resourceApiVersion: V3
routeConfigName: second-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10080
useRemoteAddress: true
name: second-listener
transportSocket:
@@ -118,6 +119,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
- filterChainMatch:
serverNames:
- bar.com
@@ -126,7 +129,7 @@
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-dest
- statPrefix: passthrough
+ statPrefix: tls-passthrough-10080
name: fifth-route
- filterChainMatch:
serverNames:
@@ -136,7 +139,7 @@
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tls-route-dest
- statPrefix: passthrough
+ statPrefix: tls-passthrough-10080
name: sixth-route
listenerFilters:
- name: envoy.filters.listener.tls_inspector
diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.clusters.yaml
index e0f57c2a695..f10d60e34b0 100644
--- a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-simple-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-simple-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-simple-1-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-simple-1-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-simple-2-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-simple-2-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,15 +55,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-simple-3-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-simple-3-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -72,14 +72,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-simple-4-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-simple-4-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml
index 962a960656f..df909c5396f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml
@@ -1,43 +1,42 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-simple-dest
- statPrefix: tcp
+ statPrefix: tcp-10080
name: tcp-route-simple
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-simple-1-dest
- statPrefix: tcp
+ statPrefix: tcp-10080
name: tcp-route-simple-1
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-simple-2-dest
- statPrefix: tcp
+ statPrefix: tcp-10080
name: tcp-route-simple-2
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-simple-3-dest
- statPrefix: tcp
+ statPrefix: tcp-10080
name: tcp-route-simple-3
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-simple-4-dest
- statPrefix: tcp
+ statPrefix: tcp-10080
name: tcp-route-simple-4
name: tcp-listener-simple
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.clusters.yaml
index 03e10ccd7fc..cc411266ad8 100644
--- a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,15 +55,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fourth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -72,14 +72,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fifth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fifth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.listeners.yaml
index 8471bb28b4f..13aea564d39 100644
--- a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate-with-custom-data.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10001
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -28,7 +27,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10001
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -53,14 +52,15 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10002
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -87,7 +87,7 @@
resourceApiVersion: V3
routeConfigName: second-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10002
useRemoteAddress: true
name: second-listener
transportSocket:
@@ -112,14 +112,15 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: second-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10003
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -148,7 +149,7 @@
serverHeaderTransformation: PASS_THROUGH
setCurrentClientCertDetails:
subject: true
- statPrefix: https
+ statPrefix: https-10003
useRemoteAddress: true
name: third-listener
transportSocket:
@@ -173,14 +174,15 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: third-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10004
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -211,7 +213,7 @@
dns: true
subject: true
uri: true
- statPrefix: https
+ statPrefix: https-10004
useRemoteAddress: true
name: fourth-listener
transportSocket:
@@ -236,14 +238,15 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: fourth-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10005
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -276,7 +279,7 @@
dns: true
subject: true
uri: true
- statPrefix: https
+ statPrefix: https-10005
useRemoteAddress: true
name: fifth-listener
transportSocket:
@@ -301,6 +304,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: fifth-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate.clusters.yaml
index 03e10ccd7fc..cc411266ad8 100644
--- a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,15 +55,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fourth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -72,14 +72,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fifth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fifth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate.listeners.yaml
index 6b3b6acded4..483ada817be 100644
--- a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-forward-client-certificate.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10001
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -28,7 +27,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10001
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -53,14 +52,15 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10002
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -87,7 +87,7 @@
resourceApiVersion: V3
routeConfigName: second-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10002
useRemoteAddress: true
name: second-listener
transportSocket:
@@ -112,14 +112,15 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: second-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10003
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -146,7 +147,7 @@
resourceApiVersion: V3
routeConfigName: third-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10003
useRemoteAddress: true
name: third-listener
transportSocket:
@@ -171,14 +172,15 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: third-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10004
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -205,7 +207,7 @@
resourceApiVersion: V3
routeConfigName: fourth-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10004
useRemoteAddress: true
name: fourth-listener
transportSocket:
@@ -230,14 +232,15 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: fourth-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10005
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -264,7 +267,7 @@
resourceApiVersion: V3
routeConfigName: fifth-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10005
useRemoteAddress: true
name: fifth-listener
transportSocket:
@@ -289,6 +292,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: fifth-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.clusters.yaml
index 4dad0aad1a7..4521d562efa 100644
--- a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tls-terminate-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tls-terminate-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.listeners.yaml
index 5c396e30fe3..20dbf81f07a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -28,7 +27,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10080
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -53,30 +52,28 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tls-terminate-dest
- statPrefix: terminate
+ statPrefix: tls-terminate-10081
name: tls-route-terminate
transportSocket:
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
commonTlsContext:
- alpnProtocols:
- - h2
- - http/1.1
tlsCertificateSdsSecretConfigs:
- name: secret-3
sdsConfig:
@@ -87,6 +84,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: false
name: second-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls.clusters.yaml
index 4dad0aad1a7..4521d562efa 100644
--- a/internal/xds/translator/testdata/out/xds-ir/mutual-tls.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tls-terminate-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tls-terminate-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls.listeners.yaml
index b1bdae764ff..b51e1c7c927 100644
--- a/internal/xds/translator/testdata/out/xds-ir/mutual-tls.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -28,7 +27,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10080
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -53,30 +52,28 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: true
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tls-terminate-dest
- statPrefix: terminate
+ statPrefix: tls-terminate-10081
name: tls-route-terminate
transportSocket:
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
commonTlsContext:
- alpnProtocols:
- - h2
- - http/1.1
tlsCertificateSdsSecretConfigs:
- name: secret-3
sdsConfig:
@@ -87,6 +84,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
requireClientCertificate: true
name: second-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.clusters.yaml
new file mode 100644
index 00000000000..430e4ae82ce
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.clusters.yaml
@@ -0,0 +1,42 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: third-route-dest
+ lbPolicy: LEAST_REQUEST
+ name: third-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: securitypolicy/envoy-gateway/policy-for-gateway/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: oauth.foo.com
+ portValue: 443
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/envoy-gateway/policy-for-gateway/0/backend/0
+ name: securitypolicy/envoy-gateway/policy-for-gateway/0
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.endpoints.yaml
new file mode 100644
index 00000000000..6c69841c2ad
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: third-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: third-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.listeners.yaml
new file mode 100644
index 00000000000..3addb294484
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.listeners.yaml
@@ -0,0 +1,83 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.oauth2/securitypolicy/envoy-gateway/policy-for-gateway
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2
+ config:
+ authScopes:
+ - openid
+ authType: BASIC_AUTH
+ authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth
+ credentials:
+ clientId: client1.apps.googleusercontent.com
+ cookieNames:
+ bearerToken: AccessToken-b0a1b740
+ idToken: IdToken-b0a1b740
+ oauthExpires: OauthExpires-b0a1b740
+ oauthHmac: OauthHMAC-b0a1b740
+ oauthNonce: OauthNonce-b0a1b740
+ refreshToken: RefreshToken-b0a1b740
+ hmacSecret:
+ name: oauth2/hmac_secret/securitypolicy/envoy-gateway/policy-for-gateway
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ tokenSecret:
+ name: oauth2/client_secret/securitypolicy/envoy-gateway/policy-for-gateway
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ defaultExpiresIn: 1800s
+ defaultRefreshTokenExpiresIn: 86400s
+ forwardBearerToken: true
+ redirectPathMatcher:
+ path:
+ exact: /bar/oauth2/callback
+ redirectUri: https://www.example.com/bar/oauth2/callback
+ retryPolicy:
+ numRetries: 3
+ retryBackOff:
+ baseInterval: 1s
+ maxInterval: 5s
+ retryOn: 5xx,gateway-error,reset
+ signoutPath:
+ path:
+ exact: /bar/logout
+ tokenEndpoint:
+ cluster: securitypolicy/envoy-gateway/policy-for-gateway/0
+ timeout: 10s
+ uri: https://oauth.foo.com/token
+ useRefreshToken: true
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: first-listener
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.routes.yaml
new file mode 100644
index 00000000000..b17df86476d
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.routes.yaml
@@ -0,0 +1,18 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ path: baz
+ name: first-route
+ route:
+ cluster: third-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.oauth2/securitypolicy/envoy-gateway/policy-for-gateway:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.secrets.yaml
new file mode 100644
index 00000000000..398ab6cef7b
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backencluster-provider.secrets.yaml
@@ -0,0 +1,8 @@
+- genericSecret:
+ secret:
+ inlineBytes: Y2xpZW50MTpzZWNyZXQK
+ name: oauth2/client_secret/securitypolicy/envoy-gateway/policy-for-gateway
+- genericSecret:
+ secret:
+ inlineBytes: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY=
+ name: oauth2/hmac_secret/securitypolicy/envoy-gateway/policy-for-gateway
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.clusters.yaml
new file mode 100644
index 00000000000..3f64db3ca35
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.clusters.yaml
@@ -0,0 +1,43 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: third-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: securitypolicy/envoy-gateway/policy-for-gateway/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: oauth.foo.com
+ portValue: 443
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/envoy-gateway/policy-for-gateway/0/backend/0
+ name: securitypolicy/envoy-gateway/policy-for-gateway/0
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.endpoints.yaml
new file mode 100644
index 00000000000..6c69841c2ad
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: third-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: third-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.listeners.yaml
new file mode 100644
index 00000000000..ab9e55eadf0
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.listeners.yaml
@@ -0,0 +1,83 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.oauth2/securitypolicy/envoy-gateway/policy-for-gateway
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2
+ config:
+ authScopes:
+ - openid
+ authType: BASIC_AUTH
+ authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth
+ credentials:
+ clientId: client1.apps.googleusercontent.com
+ cookieNames:
+ bearerToken: AccessToken-b0a1b740
+ idToken: IdToken-b0a1b740
+ oauthExpires: OauthExpires-b0a1b740
+ oauthHmac: OauthHMAC-b0a1b740
+ oauthNonce: OauthNonce-b0a1b740
+ refreshToken: RefreshToken-b0a1b740
+ hmacSecret:
+ name: oauth2/hmac_secret/securitypolicy/envoy-gateway/policy-for-gateway
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ tokenSecret:
+ name: oauth2/client_secret/securitypolicy/envoy-gateway/policy-for-gateway
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ defaultExpiresIn: 1800s
+ defaultRefreshTokenExpiresIn: 86400s
+ forwardBearerToken: true
+ redirectPathMatcher:
+ path:
+ exact: /bar/oauth2/callback
+ redirectUri: https://www.example.com/bar/oauth2/callback
+ retryPolicy:
+ numRetries: 3
+ retryBackOff:
+ baseInterval: 1s
+ maxInterval: 5s
+ retryOn: 5xx,gateway-error,reset
+ signoutPath:
+ path:
+ exact: /bar/logout
+ tokenEndpoint:
+ cluster: securitypolicy/envoy-gateway/policy-for-gateway/0
+ timeout: 10s
+ uri: https://oauth.foo.com/token
+ useRefreshToken: true
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: first-listener
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.routes.yaml
new file mode 100644
index 00000000000..b17df86476d
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.routes.yaml
@@ -0,0 +1,18 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ path: baz
+ name: first-route
+ route:
+ cluster: third-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.oauth2/securitypolicy/envoy-gateway/policy-for-gateway:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.secrets.yaml
new file mode 100644
index 00000000000..398ab6cef7b
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.secrets.yaml
@@ -0,0 +1,8 @@
+- genericSecret:
+ secret:
+ inlineBytes: Y2xpZW50MTpzZWNyZXQK
+ name: oauth2/client_secret/securitypolicy/envoy-gateway/policy-for-gateway
+- genericSecret:
+ secret:
+ inlineBytes: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY=
+ name: oauth2/hmac_secret/securitypolicy/envoy-gateway/policy-for-gateway
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.clusters.yaml
index 5309331d017..fd5ce16a3d2 100644
--- a/internal/xds/translator/testdata/out/xds-ir/oidc.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,7 +38,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -55,7 +55,6 @@
locality:
region: oauth_foo_com_443/backend/0
name: oauth_foo_com_443
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
@@ -74,7 +73,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -91,7 +90,6 @@
locality:
region: oauth_bar_com_443/backend/0
name: oauth_bar_com_443
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml
index a182efcbd8c..714f4f17ec3 100644
--- a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -32,6 +32,7 @@
idToken: IdToken-5F93C2E4
oauthExpires: OauthExpires-5F93C2E4
oauthHmac: OauthHMAC-5F93C2E4
+ oauthNonce: OauthNonce-5F93C2E4
refreshToken: RefreshToken-5F93C2E4
hmacSecret:
name: oauth2/hmac_secret/securitypolicy/default/policy-for-first-route
@@ -73,11 +74,13 @@
authorizationEndpoint: https://oauth.bar.com/oauth2/v2/auth
credentials:
clientId: client.oauth.bar.com
+ cookieDomain: example.com
cookieNames:
bearerToken: CustomAccessTokenOverride
idToken: CustomIdTokenOverride
oauthExpires: OauthExpires-5f93c2e4
oauthHmac: OauthHMAC-5f93c2e4
+ oauthNonce: OauthNonce-5f93c2e4
refreshToken: RefreshToken-5f93c2e4
hmacSecret:
name: oauth2/hmac_secret/securitypolicy/default/policy-for-second-route
@@ -117,9 +120,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/path-settings.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/path-settings.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/path-settings.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/path-settings.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/path-settings.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/path-settings.listeners.yaml
index 836cbde04b6..d20c59f8564 100644
--- a/internal/xds/translator/testdata/out/xds-ir/path-settings.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/path-settings.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -26,9 +26,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/proxy-protocol-upstream.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/proxy-protocol-upstream.clusters.yaml
index 6441952eae8..2ca45156f18 100644
--- a/internal/xds/translator/testdata/out/xds-ir/proxy-protocol-upstream.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/proxy-protocol-upstream.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
transportSocket:
name: envoy.transport_sockets.upstream_proxy_protocol
diff --git a/internal/xds/translator/testdata/out/xds-ir/proxy-protocol-upstream.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/proxy-protocol-upstream.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/proxy-protocol-upstream.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/proxy-protocol-upstream.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml
index bd23f61ee21..5f0229f4514 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,7 +55,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -72,7 +72,6 @@
locality:
region: ratelimit_cluster/backend/0
name: ratelimit_cluster
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
@@ -93,4 +92,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.listeners.yaml
index 4e74648095d..0e7cb96a26f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -37,9 +37,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml
index 9f9bc9f1dff..a0d3c8f99e6 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,7 +55,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -72,7 +72,6 @@
locality:
region: ratelimit_cluster/backend/0
name: ratelimit_cluster
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
@@ -93,4 +92,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.listeners.yaml
index 7840bfa0104..cd3d911b020 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -36,9 +36,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml
index 21ea0681611..71cc68288cb 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
trackClusterStats:
perEndpointStats: true
@@ -23,15 +23,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
trackClusterStats:
perEndpointStats: true
@@ -42,15 +42,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
trackClusterStats:
perEndpointStats: true
@@ -61,7 +61,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -78,7 +78,6 @@
locality:
region: ratelimit_cluster/backend/0
name: ratelimit_cluster
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
trackClusterStats:
@@ -101,4 +100,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.listeners.yaml
index 4e74648095d..0e7cb96a26f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -37,9 +37,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.clusters.yaml
new file mode 100644
index 00000000000..a0d3c8f99e6
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.clusters.yaml
@@ -0,0 +1,97 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: first-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: second-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: third-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: ratelimit_cluster
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: envoy-ratelimit.envoy-gateway-system.svc.cluster.local
+ portValue: 8081
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: ratelimit_cluster/backend/0
+ name: ratelimit_cluster
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ tlsCertificates:
+ - certificateChain:
+ filename: /certs/tls.crt
+ privateKey:
+ filename: /certs/tls.key
+ validationContext:
+ trustedCa:
+ filename: /certs/ca.crt
+ type: STRICT_DNS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.endpoints.yaml
new file mode 100644
index 00000000000..475b89a087c
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.endpoints.yaml
@@ -0,0 +1,36 @@
+- clusterName: first-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: first-route-dest/backend/0
+- clusterName: second-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
+- clusterName: third-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: third-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.listeners.yaml
new file mode 100644
index 00000000000..0e7cb96a26f
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.listeners.yaml
@@ -0,0 +1,44 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.ratelimit
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
+ domain: first-listener
+ enableXRatelimitHeaders: DRAFT_VERSION_03
+ rateLimitService:
+ grpcService:
+ envoyGrpc:
+ clusterName: ratelimit_cluster
+ transportApiVersion: V3
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: first-listener
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.routes.yaml
new file mode 100644
index 00000000000..459d975a9b0
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.routes.yaml
@@ -0,0 +1,88 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ prefix: /
+ name: first-route
+ route:
+ cluster: first-route-dest
+ rateLimits:
+ - actions:
+ - genericKey:
+ descriptorKey: first-route
+ descriptorValue: first-route
+ - headerValueMatch:
+ descriptorKey: rule-0-match-0
+ descriptorValue: rule-0-match-0
+ expectMatch: true
+ headers:
+ - name: x-user-id
+ stringMatch:
+ exact: one
+ - maskedRemoteAddress:
+ v4PrefixMaskLen: 16
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ path: example
+ name: second-route
+ route:
+ cluster: second-route-dest
+ rateLimits:
+ - actions:
+ - genericKey:
+ descriptorKey: second-route
+ descriptorValue: second-route
+ - requestHeaders:
+ descriptorKey: rule-0-match-0
+ headerName: x-user-id
+ - requestHeaders:
+ descriptorKey: rule-0-match-1
+ headerName: foobar
+ - maskedRemoteAddress:
+ v4PrefixMaskLen: 16
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ prefix: /
+ name: third-route
+ route:
+ cluster: third-route-dest
+ rateLimits:
+ - actions:
+ - genericKey:
+ descriptorKey: third-route
+ descriptorValue: third-route
+ - headerValueMatch:
+ descriptorKey: rule-0-match-0
+ descriptorValue: rule-0-match-0
+ expectMatch: true
+ headers:
+ - name: x-user-id
+ stringMatch:
+ exact: one
+ - maskedRemoteAddress:
+ v4PrefixMaskLen: 16
+ - actions:
+ - genericKey:
+ descriptorKey: third-route
+ descriptorValue: third-route
+ - headerValueMatch:
+ descriptorKey: rule-1-match-0
+ descriptorValue: rule-1-match-0
+ expectMatch: true
+ headers:
+ - name: x-user-id
+ stringMatch:
+ exact: two
+ - requestHeaders:
+ descriptorKey: rule-1-match-1
+ headerName: foobar
+ - maskedRemoteAddress:
+ v4PrefixMaskLen: 16
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml
index 33fc01336b8..cc94e339c02 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,15 +55,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: fourth-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -72,7 +72,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -89,7 +89,6 @@
locality:
region: ratelimit_cluster/backend/0
name: ratelimit_cluster
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
@@ -110,4 +109,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.listeners.yaml
index 4e74648095d..0e7cb96a26f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -37,9 +37,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml
index 9f9bc9f1dff..cc94e339c02 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,15 +21,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: second-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -38,15 +38,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: third-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: third-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -55,7 +55,24 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: fourth-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: fourth-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -72,7 +89,6 @@
locality:
region: ratelimit_cluster/backend/0
name: ratelimit_cluster
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocket:
@@ -93,4 +109,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit.endpoints.yaml
index 475b89a087c..f185af17da7 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit.endpoints.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit.endpoints.yaml
@@ -34,3 +34,15 @@
loadBalancingWeight: 1
locality:
region: third-route-dest/backend/0
+- clusterName: fourth-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: fourth-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit.listeners.yaml
index 4e74648095d..0e7cb96a26f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -37,9 +37,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit.routes.yaml
index 479c2cd143c..e6e83bc2bfb 100644
--- a/internal/xds/translator/testdata/out/xds-ir/ratelimit.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit.routes.yaml
@@ -55,3 +55,23 @@
descriptorValue: rule-0-match--1
upgradeConfigs:
- upgradeType: websocket
+ - match:
+ path: foo/bar/login
+ name: fourth-route
+ route:
+ cluster: fourth-route-dest
+ rateLimits:
+ - actions:
+ - genericKey:
+ descriptorKey: fourth-route
+ descriptorValue: fourth-route
+ - headerValueMatch:
+ descriptorKey: rule-0-match-0
+ descriptorValue: rule-0-match-0
+ expectMatch: false
+ headers:
+ - name: x-org-id
+ stringMatch:
+ exact: admin
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/retry-partial-invalid.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/retry-partial-invalid.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/retry-partial-invalid.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/retry-partial-invalid.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/retry-partial-invalid.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/retry-partial-invalid.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/retry-partial-invalid.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/retry-partial-invalid.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.clusters.yaml
new file mode 100644
index 00000000000..61ac2dd68c3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.clusters.yaml
@@ -0,0 +1,52 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: oidc_example_com_443
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: oidc.example.com
+ portValue: 443
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: oidc_example_com_443/backend/0
+ name: oidc_example_com_443
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ validationContext:
+ trustedCa:
+ filename: /etc/ssl/certs/ca-certificates.crt
+ sni: oidc.example.com
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.endpoints.yaml
new file mode 100644
index 00000000000..29bb6b4e444
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.listeners.yaml
new file mode 100644
index 00000000000..eb5f36cb40e
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.listeners.yaml
@@ -0,0 +1,106 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.oauth2/securitypolicy/default/policy-for-http-route
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2
+ config:
+ authScopes:
+ - openid
+ - email
+ - profile
+ authType: BASIC_AUTH
+ authorizationEndpoint: https://oidc.example.com/authorize
+ credentials:
+ clientId: prometheus
+ cookieNames:
+ bearerToken: AccessToken-5f93c2e4
+ idToken: IdToken
+ oauthExpires: OauthExpires-5f93c2e4
+ oauthHmac: OauthHMAC-5f93c2e4
+ oauthNonce: OauthNonce-5f93c2e4
+ refreshToken: RefreshToken-5f93c2e4
+ hmacSecret:
+ name: oauth2/hmac_secret/securitypolicy/default/policy-for-http-route
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ tokenSecret:
+ name: oauth2/client_secret/securitypolicy/default/policy-for-http-route
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ preserveAuthorizationHeader: true
+ redirectPathMatcher:
+ path:
+ exact: /oauth2/callback
+ redirectUri: '%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback'
+ signoutPath:
+ path:
+ exact: /logout
+ tokenEndpoint:
+ cluster: oidc_example_com_443
+ timeout: 10s
+ uri: https://oidc.example.com/oauth/token
+ useRefreshToken: false
+ - name: envoy.filters.http.jwt_authn
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
+ providers:
+ httproute/default/httproute-1/rule/0/match/0/www_example_com/exjwt:
+ claimToHeaders:
+ - claimName: email
+ headerName: x-user-email
+ forward: true
+ fromCookies:
+ - IdToken
+ issuer: https://oidc.example.com/auth/realms/example
+ normalizePayloadInMetadata:
+ spaceDelimitedClaims:
+ - scope
+ payloadInMetadata: exjwt
+ remoteJwks:
+ asyncFetch: {}
+ cacheDuration: 300s
+ httpUri:
+ cluster: oidc_example_com_443
+ timeout: 10s
+ uri: https://oidc.example.com/auth/realms/example/protocol/openid-connect/certs
+ requirementMap:
+ httproute/default/httproute-1/rule/0/match/0/www_example_com:
+ providerName: httproute/default/httproute-1/rule/0/match/0/www_example_com/exjwt
+ - name: envoy.filters.http.rbac
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: envoy-gateway/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: envoy-gateway/gateway-1/http
+ name: envoy-gateway/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.routes.yaml
new file mode 100644
index 00000000000..9c66aad8e61
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.routes.yaml
@@ -0,0 +1,74 @@
+- ignorePortInHostMatching: true
+ name: envoy-gateway/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.example.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http/www_example_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.jwt_authn:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.PerRouteConfig
+ requirementName: httproute/default/httproute-1/rule/0/match/0/www_example_com
+ envoy.filters.http.oauth2/securitypolicy/default/policy-for-http-route:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ envoy.filters.http.rbac:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+ rbac:
+ matcher:
+ matcherList:
+ matchers:
+ - onMatch:
+ action:
+ name: allow
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ name: ALLOW
+ predicate:
+ singlePredicate:
+ customMatch:
+ name: claim_matcher
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.metadata.v3.Metadata
+ value:
+ listMatch:
+ oneOf:
+ stringMatch:
+ exact: foobar
+ input:
+ name: claim
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DynamicMetadataInput
+ filter: envoy.filters.http.jwt_authn
+ path:
+ - key: exjwt
+ - key: groups
+ onNoMatch:
+ action:
+ name: default
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+ action: DENY
+ name: DENY
diff --git a/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.secrets.yaml
new file mode 100644
index 00000000000..8e76f23ccd3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.secrets.yaml
@@ -0,0 +1,8 @@
+- genericSecret:
+ secret:
+ inlineBytes: W3JlZGFjdGVkXQ==
+ name: oauth2/client_secret/securitypolicy/default/policy-for-http-route
+- genericSecret:
+ secret:
+ inlineBytes: W3JlZGFjdGVkXQ==
+ name: oauth2/hmac_secret/securitypolicy/default/policy-for-http-route
diff --git a/internal/xds/translator/testdata/out/xds-ir/simple-tls.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/simple-tls.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/simple-tls.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/simple-tls.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/simple-tls.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/simple-tls.listeners.yaml
index 30b2c8f660e..ff45c0826a6 100644
--- a/internal/xds/translator/testdata/out/xds-ir/simple-tls.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/simple-tls.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
@@ -28,7 +27,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10080
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -48,5 +47,7 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.clusters.yaml
index d53a7a1b2ce..06e9a8da524 100644
--- a/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.listeners.yaml
index 4111a2f7c1e..e56e13cfd68 100644
--- a/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -30,7 +29,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10080
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -50,6 +49,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
listenerFilters:
- name: envoy.filters.listener.tls_inspector
typedConfig:
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml
index fe51488c706..21044f7735a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml
@@ -1 +1,19 @@
-[]
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: tcp-route-simple-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: tcp-route-simple-dest
+ perConnectionBufferLimitBytes: 32768
+ trackClusterStats:
+ perEndpointStats: true
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml
index fe51488c706..7eb06a08f40 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml
@@ -1 +1,18 @@
-[]
+- clusterName: tcp-route-simple-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ - endpoint:
+ address:
+ socketAddress:
+ address: 5.6.7.8
+ portValue: 50001
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: tcp-route-simple-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml
index f0aad4ff2da..05e2fc8ffe2 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml
@@ -1,7 +1,13 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.tcp_proxy
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+ cluster: tcp-route-simple-dest
+ statPrefix: tcp-10080
name: tcp-route-enable-endpoint-stats
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.clusters.yaml
new file mode 100644
index 00000000000..809de35dd5d
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.clusters.yaml
@@ -0,0 +1,17 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: tcp-route-dual-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: tcp-route-dual-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.endpoints.yaml
new file mode 100644
index 00000000000..2b06ec86228
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.endpoints.yaml
@@ -0,0 +1,18 @@
+- clusterName: tcp-route-dual-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 192.168.1.2
+ portValue: 0
+ loadBalancingWeight: 1
+ - endpoint:
+ address:
+ socketAddress:
+ address: 2001:db8::2
+ portValue: 0
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: tcp-route-dual-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.listeners.yaml
new file mode 100644
index 00000000000..33d35dcfdbc
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.listeners.yaml
@@ -0,0 +1,15 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ ipv4Compat: true
+ portValue: 8082
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.tcp_proxy
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+ cluster: tcp-route-dual-dest
+ statPrefix: tcp-8082
+ name: tcp-route-dual
+ name: tcp-listener-dual
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.routes.yaml
new file mode 100644
index 00000000000..fe51488c706
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-listener-ipfamily.routes.yaml
@@ -0,0 +1 @@
+[]
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.clusters.yaml
new file mode 100644
index 00000000000..fc444f5c83a
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.clusters.yaml
@@ -0,0 +1,19 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: tcp-route-simple-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: tcp-route-simple-dest
+ perConnectionBufferLimitBytes: 32768
+ trackClusterStats:
+ requestResponseSizes: true
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.endpoints.yaml
new file mode 100644
index 00000000000..7eb06a08f40
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.endpoints.yaml
@@ -0,0 +1,18 @@
+- clusterName: tcp-route-simple-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ - endpoint:
+ address:
+ socketAddress:
+ address: 5.6.7.8
+ portValue: 50001
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: tcp-route-simple-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.listeners.yaml
new file mode 100644
index 00000000000..a2ac23f3a12
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.listeners.yaml
@@ -0,0 +1,13 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.tcp_proxy
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+ cluster: tcp-route-simple-dest
+ statPrefix: tcp-10080
+ name: tcp-route-enable-req-resp-sizes-stats
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.routes.yaml
new file mode 100644
index 00000000000..fe51488c706
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-req-resp-sizes-stats.routes.yaml
@@ -0,0 +1 @@
+[]
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.clusters.yaml
index 382c2857a1f..e0827c74464 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-complex-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-complex-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml
index a02d5e7cfe3..515bc6416b2 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -14,7 +13,7 @@
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-complex-dest
- statPrefix: passthrough
+ statPrefix: tls-passthrough-10080
name: tcp-route-complex
listenerFilters:
- name: envoy.filters.listener.tls_inspector
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.clusters.yaml
index c845c64037d..c6f3d6e6090 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-simple-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-simple-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml
index 10d02ab47e3..7ea9adf25bb 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml
@@ -1,15 +1,14 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-simple-dest
- statPrefix: tcp
+ statPrefix: tcp-10080
name: tcp-route-simple
name: tcp-listener-simple
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.clusters.yaml
index a7bedbf76be..45324290030 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tls-terminate-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tls-terminate-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tls-terminate-hostname-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tls-terminate-hostname-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.listeners.yaml
index c3726babf21..dc0e37419c9 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.listeners.yaml
@@ -1,29 +1,27 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tls-terminate-dest
- statPrefix: terminate
+ statPrefix: tls-terminate-10080
name: tls-route-terminate
transportSocket:
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
commonTlsContext:
- alpnProtocols:
- - h2
- - http/1.1
tlsCertificateSdsSecretConfigs:
- name: envoy-gateway-tls-secret-1
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
- filterChainMatch:
serverNames:
- '*.envoyproxy.io'
@@ -33,21 +31,20 @@
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tls-terminate-hostname-dest
- statPrefix: terminate
+ statPrefix: tls-terminate-10080
name: tls-terminate-hostname
transportSocket:
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
commonTlsContext:
- alpnProtocols:
- - h2
- - http/1.1
tlsCertificateSdsSecretConfigs:
- name: envoy-gateway-tls-secret-1
sdsConfig:
ads: {}
resourceApiVersion: V3
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
listenerFilters:
- name: envoy.filters.listener.tls_inspector
typedConfig:
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.clusters.yaml
index 849359c1385..d449d82d3f1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tcp-route-weighted-backend-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tcp-route-weighted-backend-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml
index 0736b932151..9f8af189de4 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -14,7 +13,7 @@
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tcp-route-weighted-backend-dest
- statPrefix: passthrough
+ statPrefix: tls-passthrough-10080
name: tcp-route-weighted-backend
listenerFilters:
- name: envoy.filters.listener.tls_inspector
diff --git a/internal/xds/translator/testdata/out/xds-ir/timeout.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/timeout.clusters.yaml
index e2156cb6aff..17f4bb2b315 100644
--- a/internal/xds/translator/testdata/out/xds-ir/timeout.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/timeout.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 31s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
typedExtensionProtocolOptions:
diff --git a/internal/xds/translator/testdata/out/xds-ir/timeout.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/timeout.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/timeout.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/timeout.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/tls-route-passthrough.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tls-route-passthrough.clusters.yaml
index f60942991df..08ab482392a 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tls-route-passthrough.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tls-route-passthrough.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tls-passthrough-foo-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tls-passthrough-foo-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,7 +21,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -38,7 +38,6 @@
locality:
region: tls-passthrough-bar-dest/backend/0
name: tls-passthrough-bar-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tls-route-passthrough.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tls-route-passthrough.listeners.yaml
index be0e5ea7e82..f209ec6bd68 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tls-route-passthrough.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tls-route-passthrough.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -12,7 +11,7 @@
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tls-passthrough-foo-dest
- statPrefix: passthrough
+ statPrefix: tls-passthrough-10080
name: tls-route-passthrough-foo
listenerFilters:
- name: envoy.filters.listener.tls_inspector
@@ -22,9 +21,8 @@
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -34,7 +32,7 @@
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tls-passthrough-bar-dest
- statPrefix: passthrough
+ statPrefix: tls-passthrough-10081
name: tls-route-passthrough-bar
listenerFilters:
- name: envoy.filters.listener.tls_inspector
diff --git a/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.clusters.yaml
index 4dad0aad1a7..4521d562efa 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: tls-terminate-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: tls-terminate-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.listeners.yaml
index f3f8deebcb7..8d7f6399806 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.listeners.yaml
@@ -1,8 +1,7 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
- drainType: MODIFY_ONLY
filterChains:
- filterChainMatch:
serverNames:
@@ -31,7 +30,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https
+ statPrefix: https-10080
useRemoteAddress: true
name: first-listener
transportSocket:
@@ -71,6 +70,7 @@
- rsa_pkcs1_sha1
tlsMaximumProtocolVersion: TLSv1_2
tlsMinimumProtocolVersion: TLSv1_0
+ disableStatelessSessionResumption: true
listenerFilters:
- name: envoy.filters.listener.tls_inspector
typedConfig:
@@ -79,16 +79,15 @@
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10081
- drainType: MODIFY_ONLY
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tls-terminate-dest
- statPrefix: terminate
+ statPrefix: tls-terminate-10081
name: tls-route-terminate
transportSocket:
name: envoy.transport_sockets.tls
@@ -123,5 +122,6 @@
- rsa_pkcs1_sha1
tlsMaximumProtocolVersion: TLSv1_2
tlsMinimumProtocolVersion: TLSv1_0
+ disableStatefulSessionResumption: true
name: second-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.clusters.yaml
new file mode 100644
index 00000000000..7d65a07f07e
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.clusters.yaml
@@ -0,0 +1,43 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: direct-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: tracing-0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: datadog-agent.default.svc.cluster.local
+ portValue: 8126
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: tracing-0/backend/0
+ name: tracing-0
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.endpoints.yaml
new file mode 100644
index 00000000000..20c80b3aaaa
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: direct-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: direct-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.listeners.yaml
new file mode 100644
index 00000000000..32f1b0230ff
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.listeners.yaml
@@ -0,0 +1,60 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ tracing:
+ clientSampling:
+ value: 100
+ customTags:
+ - environment:
+ defaultValue: '-'
+ name: env1
+ tag: env1
+ - literal:
+ value: value1
+ tag: literal1
+ - requestHeader:
+ defaultValue: '-'
+ name: X-Request-Id
+ tag: req1
+ overallSampling:
+ value: 100
+ provider:
+ name: envoy.tracers.datadog
+ typedConfig:
+ '@type': type.googleapis.com/envoy.config.trace.v3.DatadogConfig
+ collectorCluster: tracing-0
+ serviceName: fake-name.fake-ns
+ randomSampling:
+ value: 90
+ spawnUpstreamSpan: true
+ useRemoteAddress: true
+ name: first-listener
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.routes.yaml
new file mode 100644
index 00000000000..ea343799ac1
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog.routes.yaml
@@ -0,0 +1,14 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ prefix: /
+ name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml
index 0936f4b459a..69549cacd28 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: direct-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
trackClusterStats:
perEndpointStats: true
@@ -23,7 +23,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -40,7 +40,6 @@
locality:
region: tracing-0/backend/0
name: tracing-0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
trackClusterStats:
@@ -50,4 +49,6 @@
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml
index 760955a8da0..abac7a833a4 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,7 +27,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
tracing:
clientSampling:
value: 100
@@ -58,6 +58,5 @@
spawnUpstreamSpan: true
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.routes.yaml
index b214e8b05a3..ea343799ac1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.routes.yaml
@@ -5,8 +5,10 @@
- '*'
name: first-listener/*
routes:
- - directResponse:
- status: 500
- match:
+ - match:
prefix: /
name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.clusters.yaml
index a9d0472bfac..222bb2c6c92 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: direct-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,7 +21,7 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -38,7 +38,6 @@
locality:
region: tracing-0/backend/0
name: tracing-0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.listeners.yaml
index 25b3e9e4d40..a944c425639 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,7 +27,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
tracing:
clientSampling:
value: 100
@@ -59,6 +59,5 @@
spawnUpstreamSpan: true
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.routes.yaml
index b214e8b05a3..ea343799ac1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing-zipkin.routes.yaml
@@ -5,8 +5,10 @@
- '*'
name: first-listener/*
routes:
- - directResponse:
- status: 500
- match:
+ - match:
prefix: /
name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml
index 35bc81158da..58b42a23c8f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml
@@ -4,24 +4,25 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: direct-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: direct-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
thresholds:
- - maxRetries: 1024
+ - maxConnections: 2048
+ maxRetries: 1024
commonLbConfig:
localityWeightedLbConfig: {}
- connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ connectTimeout: 15s
+ dnsLookupFamily: V4_PREFERRED
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
loadAssignment:
@@ -38,12 +39,33 @@
locality:
region: tracing-0/backend/0
name: tracing-0
- outlierDetection: {}
- perConnectionBufferLimitBytes: 32768
+ outlierDetection:
+ baseEjectionTime: 30s
+ consecutive5xx: 5
+ consecutiveGatewayFailure: 4
+ consecutiveLocalOriginFailure: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ perConnectionBufferLimitBytes: 20971520
respectDnsTtl: true
+ transportSocket:
+ name: envoy.transport_sockets.upstream_proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport
+ config:
+ version: V2
+ transportSocket:
+ name: envoy.transport_sockets.raw_buffer
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer
type: STRICT_DNS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
'@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicitHttpConfig:
- http2ProtocolOptions: {}
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ upstreamConnectionOptions:
+ tcpKeepalive:
+ keepaliveProbes: 7
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing.listeners.yaml
index 7e5a19bcca1..3bd86857b6f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tracing.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,7 +27,7 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
tracing:
clientSampling:
value: 100
@@ -59,6 +59,5 @@
spawnUpstreamSpan: true
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing.routes.yaml
index b214e8b05a3..ea343799ac1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tracing.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing.routes.yaml
@@ -5,8 +5,10 @@
- '*'
name: first-listener/*
routes:
- - directResponse:
- status: 500
- match:
+ - match:
prefix: /
name: direct-route
+ route:
+ cluster: direct-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.clusters.yaml
index e26cb444c5c..15499f284eb 100644
--- a/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: udp-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: udp-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
trackClusterStats:
perEndpointStats: true
diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.listeners.yaml
index 8d9eaea1141..2f969eb7e95 100644
--- a/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
protocol: UDP
listenerFilters:
diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.clusters.yaml
new file mode 100644
index 00000000000..2dd1f522848
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.clusters.yaml
@@ -0,0 +1,19 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: udp-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ name: udp-route-dest
+ perConnectionBufferLimitBytes: 32768
+ trackClusterStats:
+ requestResponseSizes: true
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.endpoints.yaml
new file mode 100644
index 00000000000..2e3c84e672c
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.endpoints.yaml
@@ -0,0 +1,18 @@
+- clusterName: udp-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ - endpoint:
+ address:
+ socketAddress:
+ address: 5.6.7.8
+ portValue: 50001
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: udp-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.listeners.yaml
new file mode 100644
index 00000000000..3d1cb7b1c7d
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.listeners.yaml
@@ -0,0 +1,18 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ protocol: UDP
+ listenerFilters:
+ - name: envoy.filters.udp_listener.udp_proxy
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.UdpProxyConfig
+ matcher:
+ onNoMatch:
+ action:
+ name: route
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route
+ cluster: udp-route-dest
+ statPrefix: service
+ name: udp-route-enable-req-resp-sizes-stats
diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.routes.yaml
new file mode 100644
index 00000000000..fe51488c706
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/udp-req-resp-sizes-stats.routes.yaml
@@ -0,0 +1 @@
+[]
diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-route.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-route.clusters.yaml
index 0656b7c45e5..0a153186663 100644
--- a/internal/xds/translator/testdata/out/xds-ir/udp-route.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/udp-route.clusters.yaml
@@ -4,14 +4,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: udp-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: udp-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-route.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-route.listeners.yaml
index 317a7ddc4dd..cfcd4df467f 100644
--- a/internal/xds/translator/testdata/out/xds-ir/udp-route.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/udp-route.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
protocol: UDP
listenerFilters:
diff --git a/internal/xds/translator/testdata/out/xds-ir/upstream-tcpkeepalive.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/upstream-tcpkeepalive.clusters.yaml
index 6d5dffadf8c..1b1ee8d57b3 100644
--- a/internal/xds/translator/testdata/out/xds-ir/upstream-tcpkeepalive.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/upstream-tcpkeepalive.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: first-route-dest
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
upstreamConnectionOptions:
diff --git a/internal/xds/translator/testdata/out/xds-ir/upstream-tcpkeepalive.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/upstream-tcpkeepalive.listeners.yaml
index 67922c7444f..80ae84fd104 100644
--- a/internal/xds/translator/testdata/out/xds-ir/upstream-tcpkeepalive.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/upstream-tcpkeepalive.listeners.yaml
@@ -1,6 +1,6 @@
- address:
socketAddress:
- address: 0.0.0.0
+ address: '::'
portValue: 10080
defaultFilterChain:
filters:
@@ -27,9 +27,8 @@
resourceApiVersion: V3
routeConfigName: first-listener
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: first-listener
- drainType: MODIFY_ONLY
name: first-listener
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml
index 6a277bb94f6..ba27dfd9d28 100755
--- a/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml
@@ -4,15 +4,15 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-1/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-1/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- circuitBreakers:
@@ -21,14 +21,14 @@
commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
- dnsLookupFamily: V4_ONLY
+ dnsLookupFamily: V4_PREFERRED
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: httproute/default/httproute-2/rule/0
+ ignoreHealthOnHostRemoval: true
lbPolicy: LEAST_REQUEST
name: httproute/default/httproute-2/rule/0
- outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml
index e5ecdbb8156..e3a679d1ae0 100755
--- a/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml
@@ -90,6 +90,10 @@
timeout: 10s
uri: https://envoy-gateway:18002/42d30b4a4cc631415e6e48c02d244700da327201eb273f752cacf745715b31d9.wasm
sha256: 2a19e4f337e5223d7287e7fccd933fb01905deaff804292e5257f8c681b82bee
+ environmentVariables:
+ hostEnvKeys:
+ - SOME_KEY
+ - ANOTHER_KEY
runtime: envoy.wasm.runtime.v8
vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2
- name: envoy.filters.http.router
@@ -105,9 +109,8 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-1/http
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http
+ statPrefix: http-10080
useRemoteAddress: true
name: envoy-gateway/gateway-1/http
- drainType: MODIFY_ONLY
name: envoy-gateway/gateway-1/http
perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/tracing.go b/internal/xds/translator/tracing.go
index b2a52ec6a18..ee3f4f5e907 100644
--- a/internal/xds/translator/tracing.go
+++ b/internal/xds/translator/tracing.go
@@ -6,7 +6,6 @@
package translator
import (
- "errors"
"fmt"
"sort"
@@ -28,6 +27,7 @@ import (
const (
envoyOpenTelemetry = "envoy.tracers.opentelemetry"
envoyZipkin = "envoy.traces.zipkin"
+ envoyDatadog = "envoy.tracers.datadog"
)
type typConfigGen func() (*anypb.Any, error)
@@ -41,6 +41,16 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e
var providerConfig typConfigGen
switch tracing.Provider.Type {
+ case egv1a1.TracingProviderTypeDatadog:
+ providerName = envoyDatadog
+
+ providerConfig = func() (*anypb.Any, error) {
+ config := &tracecfg.DatadogConfig{
+ ServiceName: tracing.ServiceName,
+ CollectorCluster: tracing.Destination.Name,
+ }
+ return protocov.ToAnyWithValidation(config)
+ }
case egv1a1.TracingProviderTypeOpenTelemetry:
providerName = envoyOpenTelemetry
@@ -57,7 +67,7 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e
ServiceName: tracing.ServiceName,
}
- return protocov.ToAnyWithError(config)
+ return protocov.ToAnyWithValidation(config)
}
case egv1a1.TracingProviderTypeZipkin:
providerName = envoyZipkin
@@ -71,7 +81,7 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e
CollectorEndpointVersion: tracecfg.ZipkinConfig_HTTP_JSON,
}
- return protocov.ToAnyWithError(config)
+ return protocov.ToAnyWithValidation(config)
}
default:
return nil, fmt.Errorf("unknown tracing provider type: %s", tracing.Provider.Type)
@@ -160,14 +170,25 @@ func processClusterForTracing(tCtx *types.ResourceVersionTable, tracing *ir.Trac
return nil
}
- if err := addXdsCluster(tCtx, &xdsClusterArgs{
- name: tracing.Destination.Name,
- settings: tracing.Destination.Settings,
- tSocket: nil,
- endpointType: EndpointTypeDNS,
- metrics: metrics,
- }); err != nil && !errors.Is(err, ErrXdsClusterExists) {
- return err
+ traffic := tracing.Traffic
+ // Make sure that there are safe defaults for the traffic
+ if traffic == nil {
+ traffic = &ir.TrafficFeatures{}
}
- return nil
+ return addXdsCluster(tCtx, &xdsClusterArgs{
+ name: tracing.Destination.Name,
+ settings: tracing.Destination.Settings,
+ tSocket: nil,
+ endpointType: EndpointTypeDNS,
+ metrics: metrics,
+ loadBalancer: traffic.LoadBalancer,
+ proxyProtocol: traffic.ProxyProtocol,
+ circuitBreaker: traffic.CircuitBreaker,
+ healthCheck: traffic.HealthCheck,
+ timeout: traffic.Timeout,
+ tcpkeepalive: traffic.TCPKeepalive,
+ backendConnection: traffic.BackendConnection,
+ dns: traffic.DNS,
+ http2Settings: traffic.HTTP2,
+ })
}
diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go
index a58903e88ad..79f16d5d1b5 100644
--- a/internal/xds/translator/translator.go
+++ b/internal/xds/translator/translator.go
@@ -24,7 +24,7 @@ import (
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/wrapperspb"
- "k8s.io/utils/ptr"
+ "k8s.io/apimachinery/pkg/util/sets"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
extensionTypes "github.com/envoyproxy/gateway/internal/extension/types"
@@ -34,13 +34,12 @@ import (
"github.com/envoyproxy/gateway/internal/xds/types"
)
-var (
- ErrXdsClusterExists = errors.New("xds cluster exists")
- ErrXdsSecretExists = errors.New("xds secret exists")
+const (
+ AuthorityHeaderKey = ":authority"
+ // The dummy cluster for TCP listeners that have no routes
+ emptyClusterName = "EmptyCluster"
)
-const AuthorityHeaderKey = ":authority"
-
// Translator translates the xDS IR into xDS resources.
type Translator struct {
// GlobalRateLimit holds the global rate limit settings
@@ -168,13 +167,13 @@ func (t *Translator) notifyExtensionServerAboutListeners(
for _, l := range tCtx.XdsResources[resourcev3.ListenerType] {
listener := l.(*listenerv3.Listener)
policies := []*ir.UnstructuredRef{}
- alreadyIncludedPolicies := map[utils.NamespacedNameWithGroupKind]bool{}
+ alreadyIncludedPolicies := sets.New[utils.NamespacedNameWithGroupKind]()
for _, irListener := range findIRListenersByXDSListener(xdsIR, listener) {
for _, pol := range irListener.GetExtensionRefs() {
key := utils.GetNamespacedNameWithGroupKind(pol.Object)
- if _, found := alreadyIncludedPolicies[key]; !found {
+ if !alreadyIncludedPolicies.Has(key) {
policies = append(policies, pol)
- alreadyIncludedPolicies[key] = true
+ alreadyIncludedPolicies.Insert(key)
}
}
}
@@ -217,7 +216,12 @@ func (t *Translator) processHTTPListenerXdsTranslation(
case !xdsListenerOnSameAddressPortExists:
// Create a new UDP(QUIC) listener for HTTP3 traffic if HTTP3 is enabled
if http3Enabled {
- quicXDSListener = buildXdsQuicListener(httpListener.Name, httpListener.Address, httpListener.Port, accessLog)
+ if quicXDSListener, err = buildXdsQuicListener(httpListener.Name, httpListener.Address,
+ httpListener.Port, httpListener.IPFamily, accessLog); err != nil {
+ errs = errors.Join(errs, err)
+ continue
+ }
+
if err = tCtx.AddXdsResource(resourcev3.ListenerType, quicXDSListener); err != nil {
errs = errors.Join(errs, err)
continue
@@ -225,7 +229,13 @@ func (t *Translator) processHTTPListenerXdsTranslation(
}
// Create a new TCP listener for HTTP1/HTTP2 traffic.
- tcpXDSListener = buildXdsTCPListener(httpListener.Name, httpListener.Address, httpListener.Port, httpListener.TCPKeepalive, httpListener.Connection, accessLog)
+ if tcpXDSListener, err = buildXdsTCPListener(
+ httpListener.Name, httpListener.Address, httpListener.Port, httpListener.IPFamily,
+ httpListener.TCPKeepalive, httpListener.Connection, accessLog); err != nil {
+ errs = errors.Join(errs, err)
+ continue
+ }
+
if err = tCtx.AddXdsResource(resourcev3.ListenerType, tcpXDSListener); err != nil {
errs = errors.Join(errs, err)
continue
@@ -451,11 +461,20 @@ func (t *Translator) addRouteToRouteConfig(
vHost.Routes = append(vHost.Routes, xdsRoute)
if httpRoute.Destination != nil {
+ ea := &ExtraArgs{
+ metrics: metrics,
+ http1Settings: httpListener.HTTP1,
+ ipFamily: determineIPFamily(httpRoute.Destination.Settings),
+ }
+
+ if httpRoute.Traffic != nil && httpRoute.Traffic.HTTP2 != nil {
+ ea.http2Settings = httpRoute.Traffic.HTTP2
+ }
+
if err = processXdsCluster(
tCtx,
- httpRoute,
- httpListener.HTTP1,
- metrics,
+ &HTTPRouteTranslator{httpRoute},
+ ea,
); err != nil {
errs = errors.Join(errs, err)
}
@@ -469,7 +488,7 @@ func (t *Translator) addRouteToRouteConfig(
tSocket: nil,
endpointType: EndpointTypeStatic,
metrics: metrics,
- }); err != nil && !errors.Is(err, ErrXdsClusterExists) {
+ }); err != nil {
errs = errors.Join(errs, err)
}
}
@@ -506,7 +525,7 @@ func (t *Translator) addHTTPFiltersToHCM(filterChain *listenerv3.FilterChain, ht
for i, filter := range filterChain.Filters {
if filter.Name == wellknown.HTTPConnectionManager {
var mgrAny *anypb.Any
- if mgrAny, err = protocov.ToAnyWithError(hcm); err != nil {
+ if mgrAny, err = protocov.ToAnyWithValidation(hcm); err != nil {
return err
}
@@ -552,12 +571,19 @@ func (t *Translator) processTCPListenerXdsTranslation(
) error {
// The XDS translation is done in a best-effort manner, so we collect all
// errors and return them at the end.
- var errs error
+ var errs, err error
for _, tcpListener := range tcpListeners {
// Search for an existing listener, if it does not exist, create one.
xdsListener := findXdsListenerByHostPort(tCtx, tcpListener.Address, tcpListener.Port, corev3.SocketAddress_TCP)
if xdsListener == nil {
- xdsListener = buildXdsTCPListener(tcpListener.Name, tcpListener.Address, tcpListener.Port, tcpListener.TCPKeepalive, tcpListener.Connection, accesslog)
+ if xdsListener, err = buildXdsTCPListener(
+ tcpListener.Name, tcpListener.Address, tcpListener.Port, tcpListener.IPFamily,
+ tcpListener.TCPKeepalive, tcpListener.Connection, accesslog); err != nil {
+ // skip this listener if failed to build xds listener
+ errs = errors.Join(errs, err)
+ continue
+ }
+
if err := tCtx.AddXdsResource(resourcev3.ListenerType, xdsListener); err != nil {
// skip this listener if failed to add xds listener to the
errs = errors.Join(errs, err)
@@ -573,19 +599,7 @@ func (t *Translator) processTCPListenerXdsTranslation(
patchProxyProtocolFilter(xdsListener, tcpListener.EnableProxyProtocol)
for _, route := range tcpListener.Routes {
- if err := addXdsCluster(tCtx, &xdsClusterArgs{
- name: route.Destination.Name,
- settings: route.Destination.Settings,
- loadBalancer: route.LoadBalancer,
- proxyProtocol: route.ProxyProtocol,
- circuitBreaker: route.CircuitBreaker,
- tcpkeepalive: route.TCPKeepalive,
- healthCheck: route.HealthCheck,
- timeout: route.Timeout,
- endpointType: buildEndpointType(route.Destination.Settings),
- metrics: metrics,
- backendConnection: route.BackendConnection,
- }); err != nil && !errors.Is(err, ErrXdsClusterExists) {
+ if err := processXdsCluster(tCtx, &TCPRouteTranslator{route}, &ExtraArgs{metrics: metrics}); err != nil {
errs = errors.Join(errs, err)
}
if route.TLS != nil && route.TLS.Terminate != nil {
@@ -614,6 +628,31 @@ func (t *Translator) processTCPListenerXdsTranslation(
errs = errors.Join(errs, err)
}
}
+
+ // If there are no routes, add a route without a destination to the listener to create a filter chain
+ // This is needed because Envoy requires a filter chain to be present in the listener, otherwise it will reject the listener and report a warning
+ if len(tcpListener.Routes) == 0 {
+ emptyRouteCluster := &clusterv3.Cluster{
+ Name: emptyClusterName,
+ ClusterDiscoveryType: &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STATIC},
+ }
+
+ if findXdsCluster(tCtx, emptyClusterName) == nil {
+ if err := tCtx.AddXdsResource(resourcev3.ClusterType, emptyRouteCluster); err != nil {
+ errs = errors.Join(errs, err)
+ }
+ }
+
+ emptyRoute := &ir.TCPRoute{
+ Name: emptyClusterName,
+ Destination: &ir.RouteDestination{
+ Name: emptyClusterName,
+ },
+ }
+ if err := addXdsTCPFilterChain(xdsListener, emptyRoute, emptyClusterName, accesslog, tcpListener.Timeout, tcpListener.Connection); err != nil {
+ errs = errors.Join(errs, err)
+ }
+ }
}
return errs
}
@@ -647,16 +686,7 @@ func processUDPListenerXdsTranslation(
}
// 1:1 between IR UDPRoute and xDS Cluster
- if err := addXdsCluster(tCtx, &xdsClusterArgs{
- name: route.Destination.Name,
- settings: route.Destination.Settings,
- loadBalancer: route.LoadBalancer,
- timeout: route.Timeout,
- tSocket: nil,
- endpointType: buildEndpointType(route.Destination.Settings),
- metrics: metrics,
- backendConnection: route.BackendConnection,
- }); err != nil && !errors.Is(err, ErrXdsClusterExists) {
+ if err := processXdsCluster(tCtx, &UDPRouteTranslator{route}, &ExtraArgs{metrics: metrics}); err != nil {
errs = errors.Join(errs, err)
}
}
@@ -748,35 +778,9 @@ func findXdsEndpoint(tCtx *types.ResourceVersionTable, name string) *endpointv3.
return nil
}
-// processXdsCluster processes a xds cluster by its endpoint address type.
-func processXdsCluster(tCtx *types.ResourceVersionTable, httpRoute *ir.HTTPRoute, http1Settings *ir.HTTP1Settings, metrics *ir.Metrics) error {
- clusterArgs := &xdsClusterArgs{
- name: httpRoute.Destination.Name,
- settings: httpRoute.Destination.Settings,
- tSocket: nil,
- endpointType: buildEndpointType(httpRoute.Destination.Settings),
- http1Settings: http1Settings,
- metrics: metrics,
- useClientProtocol: ptr.Deref(httpRoute.UseClientProtocol, false),
- }
-
- // Populate traffic features.
- bt := httpRoute.Traffic
- if bt != nil {
- clusterArgs.loadBalancer = bt.LoadBalancer
- clusterArgs.proxyProtocol = bt.ProxyProtocol
- clusterArgs.circuitBreaker = bt.CircuitBreaker
- clusterArgs.healthCheck = bt.HealthCheck
- clusterArgs.timeout = bt.Timeout
- clusterArgs.tcpkeepalive = bt.TCPKeepalive
- clusterArgs.backendConnection = bt.BackendConnection
- }
-
- if err := addXdsCluster(tCtx, clusterArgs); err != nil && !errors.Is(err, ErrXdsClusterExists) {
- return err
- }
-
- return nil
+// processXdsCluster processes xds cluster with args per route.
+func processXdsCluster(tCtx *types.ResourceVersionTable, route clusterArgs, extras *ExtraArgs) error {
+ return addXdsCluster(tCtx, route.asClusterArgs(extras))
}
// findXdsSecret finds a xds secret with the same name, and returns nil if there is no match.
@@ -795,10 +799,12 @@ func findXdsSecret(tCtx *types.ResourceVersionTable, name string) *tlsv3.Secret
return nil
}
+// addXdsSecret adds a xds secret with args.
+// If the secret already exists, it skips adding the secret and returns nil
func addXdsSecret(tCtx *types.ResourceVersionTable, secret *tlsv3.Secret) error {
- // Return early if cluster with the same name exists
+ // Return early if secret with the same name exists
if c := findXdsSecret(tCtx, secret.Name); c != nil {
- return ErrXdsSecretExists
+ return nil
}
if err := tCtx.AddXdsResource(resourcev3.SecretType, secret); err != nil {
@@ -807,10 +813,15 @@ func addXdsSecret(tCtx *types.ResourceVersionTable, secret *tlsv3.Secret) error
return nil
}
+// addXdsCluster adds a xds cluster with args.
+// If the cluster already exists, it skips adding the cluster and returns nil.
func addXdsCluster(tCtx *types.ResourceVersionTable, args *xdsClusterArgs) error {
- // Return early if cluster with the same name exists
+ // Return early if cluster with the same name exists.
+ // All the current callers can all safely assume the xdsClusterArgs is the same for the clusters with the same name.
+ // If this assumption changes, the callers should call findXdsCluster first to check if the cluster already exists
+ // before calling addXdsCluster.
if c := findXdsCluster(tCtx, args.name); c != nil {
- return ErrXdsClusterExists
+ return nil
}
xdsCluster := buildXdsCluster(args)
@@ -932,8 +943,8 @@ func buildXdsUpstreamTLSSocketWthCert(tlsConfig *ir.TLSUpstreamConfig) (*corev3.
tlsCtx.CommonTlsContext.TlsParams = tlsParams
}
- if len(tlsConfig.ALPNProtocols) > 0 {
- tlsCtx.CommonTlsContext.AlpnProtocols = buildALPNProtocols(tlsConfig.ALPNProtocols)
+ if tlsConfig.ALPNProtocols != nil {
+ tlsCtx.CommonTlsContext.AlpnProtocols = tlsConfig.ALPNProtocols
}
if len(tlsConfig.ClientCertificates) > 0 {
@@ -947,7 +958,7 @@ func buildXdsUpstreamTLSSocketWthCert(tlsConfig *ir.TLSUpstreamConfig) (*corev3.
}
}
- tlsCtxAny, err := anypb.New(tlsCtx)
+ tlsCtxAny, err := protocov.ToAnyWithValidation(tlsCtx)
if err != nil {
return nil, err
}
diff --git a/internal/xds/translator/translator_test.go b/internal/xds/translator/translator_test.go
index 44d6d127bca..4d41b865afa 100644
--- a/internal/xds/translator/translator_test.go
+++ b/internal/xds/translator/translator_test.go
@@ -55,6 +55,17 @@ func TestTranslateXds(t *testing.T) {
"jsonpatch": {
requireEnvoyPatchPolicies: true,
},
+ "jsonpatch-with-jsonpath": {
+ requireEnvoyPatchPolicies: true,
+ },
+ "jsonpatch-with-jsonpath-invalid": {
+ requireEnvoyPatchPolicies: true,
+ errMsg: "no jsonPointers were found while evaluating the jsonPath",
+ },
+ "jsonpatch-add-op-empty-jsonpath": {
+ requireEnvoyPatchPolicies: true,
+ errMsg: "a patch operation must specify a path or jsonPath",
+ },
"jsonpatch-missing-resource": {
requireEnvoyPatchPolicies: true,
},
@@ -68,7 +79,7 @@ func TestTranslateXds(t *testing.T) {
},
"jsonpatch-move-op-with-value": {
requireEnvoyPatchPolicies: true,
- errMsg: "the value field can not be set for the remove operation",
+ errMsg: "value and from can't be specified with the remove operation",
},
"http-route-invalid": {
errMsg: "validation failed for xds resource",
@@ -95,7 +106,7 @@ func TestTranslateXds(t *testing.T) {
errMsg: "validation failed for xds resource",
},
"tracing-unknown-provider-type": {
- errMsg: "unknown tracing provider type: Datadog",
+ errMsg: "unknown tracing provider type: AwesomeTelemetry",
},
}
@@ -103,7 +114,6 @@ func TestTranslateXds(t *testing.T) {
require.NoError(t, err)
for _, inputFile := range inputFiles {
- inputFile := inputFile
inputFileName := testName(inputFile)
t.Run(inputFileName, func(t *testing.T) {
cfg, ok := testConfigs[inputFileName]
@@ -127,10 +137,9 @@ func TestTranslateXds(t *testing.T) {
},
FilterOrder: x.FilterOrder,
}
-
tCtx, err := tr.Translate(x)
if !strings.HasSuffix(inputFileName, "partial-invalid") && len(cfg.errMsg) == 0 {
- t.Logf(inputFileName)
+ t.Log(inputFileName)
require.NoError(t, err)
} else if len(cfg.errMsg) > 0 {
require.Error(t, err)
@@ -187,7 +196,6 @@ func TestTranslateRateLimitConfig(t *testing.T) {
require.NoError(t, err)
for _, inputFile := range inputFiles {
- inputFile := inputFile
inputFileName := testName(inputFile)
t.Run(inputFileName, func(t *testing.T) {
in := requireXdsIRListenerFromInputTestData(t, inputFile)
@@ -217,7 +225,6 @@ func TestTranslateXdsWithExtension(t *testing.T) {
require.NoError(t, err)
for _, inputFile := range inputFiles {
- inputFile := inputFile
inputFileName := testName(inputFile)
t.Run(inputFileName, func(t *testing.T) {
cfg, ok := testConfigs[inputFileName]
diff --git a/internal/xds/translator/utils.go b/internal/xds/translator/utils.go
index 10148150865..30c2f771ef0 100644
--- a/internal/xds/translator/utils.go
+++ b/internal/xds/translator/utils.go
@@ -129,13 +129,16 @@ func hcmContainsFilter(mgr *hcmv3.HttpConnectionManager, filterName string) bool
return false
}
-func createExtServiceXDSCluster(rd *ir.RouteDestination, tCtx *types.ResourceVersionTable) error {
+func createExtServiceXDSCluster(rd *ir.RouteDestination, traffic *ir.TrafficFeatures, tCtx *types.ResourceVersionTable) error {
var (
endpointType EndpointType
tSocket *corev3.TransportSocket
- err error
)
+ // Make sure that there are safe defaults for the traffic
+ if traffic == nil {
+ traffic = &ir.TrafficFeatures{}
+ }
// Get the address type from the first setting.
// This is safe because no mixed address types in the settings.
addrTypeState := rd.Settings[0].AddressType
@@ -144,16 +147,21 @@ func createExtServiceXDSCluster(rd *ir.RouteDestination, tCtx *types.ResourceVer
} else {
endpointType = EndpointTypeStatic
}
-
- if err = addXdsCluster(tCtx, &xdsClusterArgs{
- name: rd.Name,
- settings: rd.Settings,
- tSocket: tSocket,
- endpointType: endpointType,
- }); err != nil && !errors.Is(err, ErrXdsClusterExists) {
- return err
- }
- return nil
+ return addXdsCluster(tCtx, &xdsClusterArgs{
+ name: rd.Name,
+ settings: rd.Settings,
+ tSocket: tSocket,
+ loadBalancer: traffic.LoadBalancer,
+ proxyProtocol: traffic.ProxyProtocol,
+ circuitBreaker: traffic.CircuitBreaker,
+ healthCheck: traffic.HealthCheck,
+ timeout: traffic.Timeout,
+ tcpkeepalive: traffic.TCPKeepalive,
+ backendConnection: traffic.BackendConnection,
+ endpointType: endpointType,
+ dns: traffic.DNS,
+ http2Settings: traffic.HTTP2,
+ })
}
// addClusterFromURL adds a cluster to the resource version table from the provided URL.
@@ -186,8 +194,45 @@ func addClusterFromURL(url string, tCtx *types.ResourceVersionTable) error {
clusterArgs.tSocket = tSocket
}
- if err = addXdsCluster(tCtx, clusterArgs); err != nil && !errors.Is(err, ErrXdsClusterExists) {
- return err
+ return addXdsCluster(tCtx, clusterArgs)
+}
+
+// determineIPFamily determines the IP family based on multiple destination settings
+func determineIPFamily(settings []*ir.DestinationSetting) *egv1a1.IPFamily {
+ // If there's only one setting, return its IPFamily directly
+ if len(settings) == 1 {
+ return settings[0].IPFamily
+ }
+
+ hasIPv4 := false
+ hasIPv6 := false
+ hasDualStack := false
+
+ for _, setting := range settings {
+ if setting.IPFamily == nil {
+ continue
+ }
+
+ switch *setting.IPFamily {
+ case egv1a1.IPv4:
+ hasIPv4 = true
+ case egv1a1.IPv6:
+ hasIPv6 = true
+ case egv1a1.DualStack:
+ hasDualStack = true
+ }
+ }
+
+ switch {
+ case hasDualStack:
+ return ptr.To(egv1a1.DualStack)
+ case hasIPv4 && hasIPv6:
+ return ptr.To(egv1a1.DualStack)
+ case hasIPv4:
+ return ptr.To(egv1a1.IPv4)
+ case hasIPv6:
+ return ptr.To(egv1a1.IPv6)
+ default:
+ return nil
}
- return nil
}
diff --git a/internal/xds/translator/utils_test.go b/internal/xds/translator/utils_test.go
new file mode 100644
index 00000000000..588c68690b6
--- /dev/null
+++ b/internal/xds/translator/utils_test.go
@@ -0,0 +1,112 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package translator
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "k8s.io/utils/ptr"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/ir"
+)
+
+func TestDetermineIPFamily(t *testing.T) {
+ tests := []struct {
+ name string
+ settings []*ir.DestinationSetting
+ want *egv1a1.IPFamily
+ }{
+ {
+ name: "nil settings should return nil",
+ settings: nil,
+ want: nil,
+ },
+ {
+ name: "empty settings should return nil",
+ settings: []*ir.DestinationSetting{},
+ want: nil,
+ },
+ {
+ name: "single IPv4 setting",
+ settings: []*ir.DestinationSetting{
+ {IPFamily: ptr.To(egv1a1.IPv4)},
+ },
+ want: ptr.To(egv1a1.IPv4),
+ },
+ {
+ name: "single IPv6 setting",
+ settings: []*ir.DestinationSetting{
+ {IPFamily: ptr.To(egv1a1.IPv6)},
+ },
+ want: ptr.To(egv1a1.IPv6),
+ },
+ {
+ name: "single DualStack setting",
+ settings: []*ir.DestinationSetting{
+ {IPFamily: ptr.To(egv1a1.DualStack)},
+ },
+ want: ptr.To(egv1a1.DualStack),
+ },
+ {
+ name: "mixed IPv4 and IPv6 should return DualStack",
+ settings: []*ir.DestinationSetting{
+ {IPFamily: ptr.To(egv1a1.IPv4)},
+ {IPFamily: ptr.To(egv1a1.IPv6)},
+ },
+ want: ptr.To(egv1a1.DualStack),
+ },
+ {
+ name: "DualStack with IPv4 should return DualStack",
+ settings: []*ir.DestinationSetting{
+ {IPFamily: ptr.To(egv1a1.DualStack)},
+ {IPFamily: ptr.To(egv1a1.IPv4)},
+ },
+ want: ptr.To(egv1a1.DualStack),
+ },
+ {
+ name: "DualStack with IPv6 should return DualStack",
+ settings: []*ir.DestinationSetting{
+ {IPFamily: ptr.To(egv1a1.DualStack)},
+ {IPFamily: ptr.To(egv1a1.IPv6)},
+ },
+ want: ptr.To(egv1a1.DualStack),
+ },
+ {
+ name: "mixed with nil IPFamily should be ignored",
+ settings: []*ir.DestinationSetting{
+ {IPFamily: ptr.To(egv1a1.IPv4)},
+ {IPFamily: nil},
+ {IPFamily: ptr.To(egv1a1.IPv6)},
+ },
+ want: ptr.To(egv1a1.DualStack),
+ },
+ {
+ name: "multiple IPv4 settings should return IPv4",
+ settings: []*ir.DestinationSetting{
+ {IPFamily: ptr.To(egv1a1.IPv4)},
+ {IPFamily: ptr.To(egv1a1.IPv4)},
+ },
+ want: ptr.To(egv1a1.IPv4),
+ },
+ {
+ name: "multiple IPv6 settings should return IPv6",
+ settings: []*ir.DestinationSetting{
+ {IPFamily: ptr.To(egv1a1.IPv6)},
+ {IPFamily: ptr.To(egv1a1.IPv6)},
+ },
+ want: ptr.To(egv1a1.IPv6),
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got := determineIPFamily(tt.settings)
+ assert.Equal(t, tt.want, got)
+ })
+ }
+}
diff --git a/internal/xds/translator/wasm.go b/internal/xds/translator/wasm.go
index b8777e3805c..34b1087d5cc 100644
--- a/internal/xds/translator/wasm.go
+++ b/internal/xds/translator/wasm.go
@@ -118,30 +118,38 @@ func wasmConfig(wasm ir.Wasm) (*wasmfilterv3.Wasm, error) {
return nil, err
}
+ vmConfig := &wasmv3.VmConfig{
+ VmId: wasm.Name, // Do not share VMs across different filters
+ Runtime: vmRuntimeV8,
+ Code: &corev3.AsyncDataSource{
+ Specifier: &corev3.AsyncDataSource_Remote{
+ Remote: &corev3.RemoteDataSource{
+ HttpUri: &corev3.HttpUri{
+ Uri: wasm.Code.ServingURL,
+ HttpUpstreamType: &corev3.HttpUri_Cluster{
+ Cluster: wasmHTTPServerCluster,
+ },
+ Timeout: &durationpb.Duration{
+ Seconds: defaultExtServiceRequestTimeout,
+ },
+ },
+ Sha256: wasm.Code.SHA256,
+ },
+ },
+ },
+ }
+
+ if wasm.HostKeys != nil {
+ vmConfig.EnvironmentVariables = &wasmv3.EnvironmentVariables{
+ HostEnvKeys: wasm.HostKeys,
+ }
+ }
+
filterConfig = &wasmfilterv3.Wasm{
Config: &wasmv3.PluginConfig{
Name: wasm.WasmName,
Vm: &wasmv3.PluginConfig_VmConfig{
- VmConfig: &wasmv3.VmConfig{
- VmId: wasm.Name, // Do not share VMs across different filters
- Runtime: vmRuntimeV8,
- Code: &corev3.AsyncDataSource{
- Specifier: &corev3.AsyncDataSource_Remote{
- Remote: &corev3.RemoteDataSource{
- HttpUri: &corev3.HttpUri{
- Uri: wasm.Code.ServingURL,
- HttpUpstreamType: &corev3.HttpUri_Cluster{
- Cluster: wasmHTTPServerCluster,
- },
- Timeout: &durationpb.Duration{
- Seconds: defaultExtServiceRequestTimeout,
- },
- },
- Sha256: wasm.Code.SHA256,
- },
- },
- },
- },
+ VmConfig: vmConfig,
},
Configuration: configAny,
FailOpen: wasm.FailOpen,
diff --git a/internal/xds/types/resourceversiontable_test.go b/internal/xds/types/resourceversiontable_test.go
index 8da1c0cc7ca..5fe96253bc8 100644
--- a/internal/xds/types/resourceversiontable_test.go
+++ b/internal/xds/types/resourceversiontable_test.go
@@ -71,7 +71,6 @@ func TestDeepCopy(t *testing.T) {
},
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
if tc.out == nil {
require.Nil(t, tc.in.DeepCopy())
@@ -531,7 +530,6 @@ func TestAddOrReplaceXdsResource(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := tc.tableIn.AddOrReplaceXdsResource(tc.typeIn, tc.resourceIn, tc.funcIn)
require.NoError(t, err)
@@ -887,7 +885,6 @@ func TestInvalidAddXdsResource(t *testing.T) {
},
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := tc.tableIn.AddOrReplaceXdsResource(tc.typeIn, tc.resourceIn, tc.funcIn)
require.Error(t, err)
diff --git a/release-notes/current.yaml b/release-notes/current.yaml
new file mode 100644
index 00000000000..4d61dd6b19f
--- /dev/null
+++ b/release-notes/current.yaml
@@ -0,0 +1,35 @@
+date: Pending
+
+# Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs.
+breaking changes: |
+ The Container `ports` field of the gateway instance has been removed, which will cause the gateway Pod to be rebuilt when upgrading the version.
+ ClientTrafficPolicy previously treated an empty TLS ALPNProtocols list as being undefined and applied Envoy Gateway defaults.
+ An empty TLS ALPNProtocols list is now treated as user-defined disablement of the TLS ALPN extension.
+ Outlier detection (passive health check) is now disabled by default.
+ refer to https://gateway.envoyproxy.io/docs/api/extension_types/#backendtrafficpolicy for working with passive health checks.
+
+# Updates addressing vulnerabilities, security flaws, or compliance requirements.
+security updates: |
+ Add a security update here
+
+# New features or capabilities added in this release.
+new features: |
+ Added support for trusted CIDRs in the ClientIPDetectionSettings API
+ Added support for sending attributes to external processor in EnvoyExtensionPolicy API
+ Added support for patching EnvoyProxy.spec.provider.kubernetes.envoyHpa and EnvoyProxy.spec.provider.kubernetes.envoyPDB
+
+# Fixes for bugs identified in previous versions.
+bug fixes: |
+
+# Enhancements that improve performance.
+performance improvements: |
+ Add a performance improvement here
+
+# Deprecated features or APIs.
+deprecations: |
+ Add a deprecation here
+
+# Other notable changes not covered by the above sections.
+Other changes: |
+ [SecurityPolicy] Modify the JWT Provider Issuer validation constraint
+ Add support for Kubernetes 1.32.x in the test matrix, and remove support for Kubernetes 1.28.x.
diff --git a/release-notes/v1.1.1.yaml b/release-notes/v1.1.1.yaml
new file mode 100644
index 00000000000..ac5f40ea678
--- /dev/null
+++ b/release-notes/v1.1.1.yaml
@@ -0,0 +1,42 @@
+date: September 11, 2024
+
+changes:
+ - area: documentation
+ change: |
+ Bumped Golang version to 1.22.7
+
+
+ - area: conformance
+ change: |
+ Enabled GatewayHTTPListenerIsolation test
+
+
+ - area: testing
+ change: |
+ Fix download URL of envoy proxy WASM examples used in tests
+
+
+ - area: translator
+ change: |
+ Fixed url rewrite to remove trailing slash
+ Isolate HTTP route tables to listener according to Gateway-API specifications
+ Fixed identification of ReferenceGrant when multiple ReferenceGrants exist in a namespace
+ Fixed added header values as a command and space delimited list
+ Fixed assertion on expected status in active HTTP healthcheck
+ Fixed rejection of invalid Backends referenced by xRoutes
+ Fixed support for empty SlowStart configuration when using LeastRequest loadbalancing
+ Fixed update of status for Backends
+
+
+ - area: infra-manager
+ change: |
+ Pin ratelimit version to 26f28d78
+ Reduce readinessProbe failureThreshold and periodSeconds of proxy
+ Expose ratelimit statsd
+
+
+ - area: providers
+ change: |
+ Fixed error returned when referenced Configmap or Secret is not found
+ Use component name in Envoy Gateway logs
+
diff --git a/release-notes/v1.1.2.yaml b/release-notes/v1.1.2.yaml
new file mode 100644
index 00000000000..a257ea677f6
--- /dev/null
+++ b/release-notes/v1.1.2.yaml
@@ -0,0 +1,16 @@
+date: September 24, 2024
+
+changes:
+ - area: translator
+ change: |
+ Fixed handling of sectionName in BackendTLSPolicy for Backend resource
+
+
+ - area: infra-manager
+ change: |
+ Pin Envoy Proxy version to v1.32.2
+ Change Envoy listener drain strategy from gradual to immediate
+
+ - area: providers
+ change: |
+ Fixed reconciliation of HTTPRoutes when labels change
diff --git a/release-notes/v1.1.3.yaml b/release-notes/v1.1.3.yaml
new file mode 100644
index 00000000000..7e2f9070888
--- /dev/null
+++ b/release-notes/v1.1.3.yaml
@@ -0,0 +1,28 @@
+date: November 1, 2024
+
+# Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs.
+breaking changes: |
+
+# New features or capabilities added in this release.
+new features: |
+
+# Fixes for bugs identified in previous versions.
+bug fixes: |
+ Fixed unsupported listener protocol type causing an error while updating Gateway Status
+ Fixed some status updates were being discarded by the status updater
+ Fixed error level logging for admin and metrics modules
+ Fixed Dashboard typos
+ Fixed Ratelimit Deployment ignoring pod labels and annotation merge
+ Fixed the API Server receives unnecessary requests
+ Fixed set invalid Listener.SupportedKinds to empty list
+ Fixed losing timeout settings that originate from the route when translating the backend traffic policy
+ Fixed xds translation failure when wasm http code source configured without sha
+
+# Enhancements that improve performance.
+performance improvements: |
+
+# Other notable changes not covered by the above sections.
+Other changes: |
+ Bumped Envoy proxy to 1.31.3
+ Bumped github.com/docker/docker to 27.3.1+incompatible
+
diff --git a/release-notes/v1.1.4.yaml b/release-notes/v1.1.4.yaml
new file mode 100644
index 00000000000..09b06e829e2
--- /dev/null
+++ b/release-notes/v1.1.4.yaml
@@ -0,0 +1,16 @@
+date: December 12, 2024
+
+# Fixes for bugs identified in previous versions.
+bug fixes: |
+ Fixed validate proto messages before converting them to anypb.Any
+ Fixed BackendTlsPolicy specify multiple targetRefs of the same service, only one will work
+ Fixed Envoy rejecting TCP Listeners that have no attached TCPRoutes
+ Fixed frequent 503 errors when connecting to a Service experiencing high Pod churn
+ Fixed reference grant from EnvoyExtensionPolicy to referenced ext-proc backend not respected
+ Fixed BackendTrafficPolicy not applying to Gateway Route when Route has a Request Timeout defined
+
+# Other notable changes not covered by the above sections.
+Other changes: |
+ Bumped Rate Limit to 49af5cca
+ Bumped golang.org/x/crypto to 0.31.0
+
diff --git a/release-notes/v1.2.0-rc.1.yaml b/release-notes/v1.2.0-rc.1.yaml
new file mode 100644
index 00000000000..0ff64d9325f
--- /dev/null
+++ b/release-notes/v1.2.0-rc.1.yaml
@@ -0,0 +1,132 @@
+date: October 25, 2024
+
+# Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs.
+breaking changes: |
+ Gateway API GRPCRoute and ReferenceGrant v1alpha2 have been removed.
+ Please refer to the [Gateway API v1.2.0 documentation](https://github.com/kubernetes-sigs/gateway-api/releases) for more information.
+ Removed default CPU limit of the Envoy Gateway deployment
+ Changed default Envoy shutdown settings: drain strategy has been changed to immediate, default minDrainDuration, drainTimeout and terminationGracePeriodSeconds have been set to 10s, 60s and 360s respectively
+
+# New features or capabilities added in this release.
+new features: |
+ Added support for Gateway-API v1.2.0
+ Added support for IPv4/IPv6 Dual Stack for Envoy listeners and BackendRef resources
+ Added support for EG standalone(host deployment) mode (experimental)
+ Added support for JWT claims based Authorization in SecurityPolicy CRD
+ Added support for Direct Response in HTTPRouteFilter CRD
+ Added support for Response Override in BackendTrafficPolicy CRD
+ Added support for RequestTimeout in BackendTrafficPolicy CRD
+ Added support for inverting header matches for rate limit in BackendTrafficPolicy CRD
+ Added support for client TLS session resumption in ClientTrafficPolicy CRD
+ Added support for HTTPRouteFilter and path regex rewrite
+ Added support for host header rewrite in HTTPRouteFilter CRD
+ Added support for Listener Access Log in EnvoyProxy CRD
+ Added support for Datadog tracing support in EnvoyProxy CRD
+ Added support for request response sizes stats in EnvoyProxy CRD
+ Added support for wildcard matching for CORS AllowMethods and AllowHeaders settings in SecurityPolicy CRD
+ Added support for match conditions for access log in EnvoyProxy CRD
+ Added support for using BackendCluster to represent OIDCProvider
+ Added support for RecomputeRoute for ExtAuth in SecurityPolicy CRD
+ Added support for sharing token cookies between multiple domains in SecurityPolicy CRD
+ Added support for JSONPatches for proxy bootstrap modifications in EnvoyProxy CRD
+ Added support for LB priority for non xRoute endpoints
+ Added support for configuring the GRPC Health Checker in the BackendTrafficPolicy CRD
+ Added support for early request header mutation in the ClientTrafficPolicy CRD
+ Added support for JsonPath in the EnvoyPatchPolicy CRD
+ Added support for cluster settings for tracing and access log backends in EnvoyProxy CRD
+ Added support for cluster settings for non xRoute-generated backend refs
+ Added support for socket buffer limit field in ClientTrafficPolicy and BackendTrafficPolicy CRD
+ Added support for http2 upstream settings in BackendTrafficPolicy CRD
+ Added support for DNS resolution settings in BackendTrafficPolicy CRD
+ Added support for configuring service annotations in the Envoy Gateway helm chart
+ Added support for configuring priorityClassName to Envoy Gateway helm chart
+ Added support for ratelimit metrics monitoring in grafana in the addons helm chart
+ Added support for default user group and user id for the SecurityContexts in the Envoy Gateway helm chart
+ Added support for maxUnavailable in the PodDisruptionBudget in the Envoy Gateway helm chart
+ Added support for configuring NodeSelector in the Envoy Gateway helm chart
+ Added support for nonce in the OIDC auth flow
+ Added support for choosing an HTTPRoute's non-wildcard hostname as the default Host
+ Added support for returning 500 when EnvoyExtensionTrafficPolicy translation fails
+ Added support for returning 500 when SecurityPolicy translation fails
+ Added support for multiple backendRefs for ExtAuth and ExtProc
+ Added support for session persistence in HTTPRoute rules
+ Added support for the Backend resource for ExtAuth
+ Added support for target selectors on Envoy Gateway Extension Server policies
+ Added support for non-Kubernetes Backends for TLSRoute
+ Added support for fallback to the Backend API
+ Added support for reloadable EnvoyGateway configuration
+ Added support for adding Labels to the Envoy Service
+ Added support for custom name for ratelimit deployment
+ Added default SecurityContext for EG components
+ Added startupProbe to all provisioned containers
+ Added support for local validations for egctl translate and file provider
+ Added support for egctl x collect to collect information from the cluster for debugging
+ Added support for a native prometheus metrics endpoint in the ratelimit server
+
+# Fixes for bugs identified in previous versions.
+bug fixes: |
+ Fixed unsupported listener protocol type causing an error while updating Gateway Status
+ Fixed some status updates were being discarded by the status updater
+ Fixed Gateway crash adding BackendTLSPolicy to External Backend of an HTTPRoute
+ Fixed Delay in SecurityPolicy change propagation for HTTPRoute when using targetSelectors
+ Fixed JSONPath not correctly translated to JSONPatch paths
+ Fixed allow empty slowStart when using LeastRequest
+ Fixed Backends which should be rejected are still used as an HTTPRoute's destination
+ Fixed losing timeout settings that originate from the route when translating the backend traffic policy
+ Fixed Backend resources don't get status updates
+ Fixed Active Health check requires expectedStatuses field to work
+ Fixed HTTPHeaderFilter processing doesn't correctly support multiple header values
+ Fixed multiple reference grants in same namespace
+ Fixed upstream get unwanted /.
+ Fixed creation of SecurityPolicy with targetSelectors fails
+ Fixed wrong gateway is chosen as HTTPRoute parent
+ Fixed override issue for EEP
+ Fixed nil pointer err translating hash load balancing
+ Fixed ratelimit does not work across multiple GatewayClasses
+ Fixed upstream mTLS only works for HTTPS listeners
+ Fixed nil pointer if backedtls.minVersion is set but backedtls.maxVersion is not
+ Fixed empty connection limit causes XDS rejection
+ Fixed ratelimit not working with both headers and cidr matches
+ Fixed EDS didn't update when deployments was created after services
+ Fixed RBAC issue for deleting infrastructure resources
+ Fixed customized infrastructure resources not being deleted
+ Fixed Gateways never become ready/programmed when running Envoy as a Daemonset
+ Fixed Ratelimit Deployment ignoring pod labels and annotation merge
+ Fixed the API Server receives unnecessary requests
+ Fixed terminating envoy pods don't respond with "Connection: close" (H1) or GOAWAY(H2) on shutdown, switch to an immediate drain strategy
+ Fixed ratelimit statsd not working
+ Fixed not generating selector of deployment/daemonset based on the custom label configuration of EnvoyProxy
+ Fixed egctl experimental translate using a wrong ns
+
+# Enhancements that improve performance.
+performance improvements: |
+ Fixed repeated resources and optimize memory usage
+
+# Other notable changes not covered by the above sections.
+Other changes: |
+ Removed grafana test framework from the addons helm chart
+ Disabled ALPN for non-HTTP routes
+ Added statPrefix for HCM and TCPProxy
+ Enabled GatewayHTTPListenerIsolation conformance test
+ Enabled GRPC conformance profile
+ Enabled HTTPRouteBackendRequestHeaderModifier conformance test
+ Added e2e test for Daemonset mode
+ Updated upgrades tests to use VERSION env variable
+ Fixed OVS scanner wrong license warnings
+ Added e2e test for TLS session resumption
+ Added heap profile into benchmark report
+ Added e2e test for RecomputeRoute in ExtAuth
+ Added benchmark memory profiles into report
+ Fixed flaky gateway_with_conflicted_listener_cannot_be_merged e2e test
+ Fixed flaky Zipkin Tracing e2e test
+ Added e2e test for cookie based consistent hash load balancing
+ Added e2e test for load balancing
+ Fixed flaky authorization tests
+ Enabled upgrade test
+ Fixed flaky basic auth e2e test
+ Enabled use-client-protocol e2e test
+ Added performance benchmarking test for 1000 HTTPRoutes
+ Added e2e test for Datadog tracing
+ Added e2e tests for ratelimit invert matching headers
+ Reduced readinessProbe failureThreshold and periodSeconds
+ Bumped go-control-plane to v0.13.1
diff --git a/release-notes/v1.2.0.yaml b/release-notes/v1.2.0.yaml
new file mode 100644
index 00000000000..c87a1d2c1d5
--- /dev/null
+++ b/release-notes/v1.2.0.yaml
@@ -0,0 +1,140 @@
+date: November 6, 2024
+
+# Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs or updating default values.
+breaking changes: |
+ Gateway API GRPCRoute and ReferenceGrant v1alpha2 have been removed
+ Please refer to the [Gateway API v1.2.0 documentation](https://github.com/kubernetes-sigs/gateway-api/releases) for more information
+ Removed default CPU limit of the Envoy Gateway deployment, to eliminate CPU throttling
+ Changed default Envoy shutdown settings: drain strategy has been changed to immediate, default minDrainDuration, drainTimeout and terminationGracePeriodSeconds have been set to 10s, 60s and 360s respectively
+ Set ignore_health_on_host_removal to true for clusters with static endpoints This was done to speed up removal of static endpoints by the control plane when active health check is configured
+ Xds and Infra IR logs are logged at Debug level instead of Info level. They will now not be seen by default in Envoy Gateway logs. You can change the logging level to default: debug to view them
+
+# New features or capabilities added in this release.
+new features: |
+ Added support for Gateway-API v1.2.0
+ Added support for IPv4/IPv6 Dual Stack for EnvoyProxy fleet and BackendRef resources
+ Added experimental support for EG standalone(host deployment) mode
+ Added support for JWT claims based Authorization in SecurityPolicy CRD
+ Added support for Response Override in BackendTrafficPolicy CRD
+ Added support for RequestTimeout in BackendTrafficPolicy CRD
+ Added support for inverting header matches for Rate Limit in BackendTrafficPolicy CRD
+ Added support for client TLS session resumption in ClientTrafficPolicy CRD
+ Added support for HTTPRouteFilter and path regex rewrite
+ Added support for host header rewrite in HTTPRouteFilter CRD
+ Added support for Listener Access Log in EnvoyProxy CRD
+ Added support for Datadog tracing support in EnvoyProxy CRD
+ Added support for request response sizes stats in EnvoyProxy CRD
+ Added support for modifying container SecurityContext for Envoy Gateway deployment in Helm
+ Added support for wildcard matching for CORS AllowMethods and AllowHeaders settings in SecurityPolicy CRD
+ Added support for match conditions for access log in EnvoyProxy CRD
+ Added support for using BackendCluster to represent OIDCProvider
+ Added support for RecomputeRoute for ExtAuth in SecurityPolicy CRD
+ Added support for sharing token cookies between multiple domains in SecurityPolicy CRD
+ Added support for JSONPatches for proxy bootstrap modifications in EnvoyProxy CRD
+ Added support for Active Passive Failover Backends
+ Added support for configuring the GRPC Health Checker in the BackendTrafficPolicy CRD
+ Added support for early request header mutation in the ClientTrafficPolicy CRD
+ Added support for JsonPath in the EnvoyPatchPolicy CRD
+ Added support for cluster settings for tracing and access log backends in EnvoyProxy CRD
+ Added support for cluster settings for non xRoute-generated backend refs
+ Added support for socket buffer limit field in ClientTrafficPolicy and BackendTrafficPolicy CRD
+ Added support for http2 upstream settings in BackendTrafficPolicy CRD
+ Added support for DNS resolution settings in BackendTrafficPolicy CRD
+ Added support for configuring service annotations in the Envoy Gateway helm chart
+ Added support for configuring priorityClassName to Envoy Gateway helm chart
+ Added support for ratelimit metrics monitoring in grafana in the addons helm chart
+ Added support for default user group and user id for the SecurityContexts in the Envoy Gateway helm chart
+ Added support for maxUnavailable in the PodDisruptionBudget in the Envoy Gateway helm chart
+ Added support for configuring NodeSelector in the Envoy Gateway helm chart
+ Added support for nonce in the OIDC auth flow
+ Added support for choosing an HTTPRoute's non-wildcard hostname as the default Host
+ Added support for returning 500 when EnvoyExtensionTrafficPolicy translation fails
+ Added support for returning 500 when SecurityPolicy translation fails
+ Added support for multiple backendRefs for ExtAuth and ExtProc
+ Added support for session persistence in HTTPRoute rules
+ Added support for the Backend resource for ExtAuth
+ Added support for target selectors on Envoy Gateway Extension Server policies
+ Added support for non-Kubernetes Backends for TLSRoute
+ Added support for fallback to the Backend API
+ Added support for reloadable EnvoyGateway configuration
+ Added support for adding Labels to the Envoy Service
+ Added support for custom name for ratelimit deployment
+ Added default SecurityContext for EG components
+ Added startupProbe to all provisioned containers
+ Added support for local validations for egctl translate and file provider
+ Added support for egctl x collect to collect information from the cluster for debugging
+ Added support for a native prometheus metrics endpoint in the ratelimit server
+
+# Fixes for bugs identified in previous versions.
+bug fixes: |
+ Fixed xDS translation failing when the WASM HTTP code source was configured without an SHA
+ Fixed unsupported listener protocol types causing errors while updating Gateway status
+ Fixed unsupported listener protocol types causing errors while updating Gateway status
+ Fixed invalid sectionName in BackendTLSPolicy for Backend
+ Fixed Delay in SecurityPolicy change propagation for HTTPRoute when using targetSelectors
+ Fixed JSONPath not being correctly translated to JSONPatch paths
+ Fixed allowing an empty slowStart value when using LeastRequest
+ Fixed updating the HTTPRoute status correctly when the linked Backend resource is invalid
+ Fixed timeout settings originating from the route being lost when translating the backend traffic policy
+ Fixed Backend resources not receiving status updates
+ Fixed active health checks requiring the expectedStatuses field to function correctly
+ Fixed HTTPHeaderFilter processing not correctly supporting multiple header values
+ Fixed reconciling multiple ReferenceGrants within the same namespace
+ Fixed unwanted / appearing in the Path when using Prefix Rewrites
+ Fixed incorrect gateway being selected as the HTTPRoute parent
+ Fixed override issues for EnvoyExtensionPolicy
+ Fixed nil pointer error when translating hash load balancing
+ Fixed nil pointer if backedtls.minVersion is set but backedtls.maxVersion is not
+ Fixed empty connection limits causing xDS rejection
+ Fixed rate limiting not working with both headers and CIDR matches
+ Fixed EDS not updating when deployments were created after services
+ Fixed RBAC issue for deleting infrastructure resources
+ Fixed gateways never reaching ready/programmed status when running Envoy as a Daemonset
+ Fixed rate limit deployment ignoring pod labels and annotation merges
+ Fixed the API Server receives unnecessary requests
+ Fixed egctl experimental translate using an incorrect namespace
+ Fixed reconciliation not being triggered for Secret updates referenced by a BackendTLSPolicy
+ Fixed xDS translation failure when WASM HTTP code source was configured without an SHA
+ Fixed HTTPRoute status displaying only one parent when targeting multiple gateways from different GatewayClasses
+ Fixed Route with multiple parents having an incorrect namespace in the parentRef status
+ Fixed BackendTlsPolicy specifying multiple targetRefs for the same service, to work
+
+# Enhancements that improve performance.
+performance improvements: |
+ Optimize memory usage by only storing distinct resources
+
+# Other notable changes not covered by the above sections.
+Other changes: |
+ Upgraded Envoy Proxy to v1.32.1
+ Reduced the amount of configuration logging, and make it line-delimited friendly
+ Made watching alpha CRDs optional, so that Envoy Gateway can run with older Gateway Api versions
+ Removed grafana test framework from the addons helm chart
+ Disabled ALPN for non-HTTP routes
+ Added statPrefix for HCM and TCPProxy
+ Enabled GatewayHTTPListenerIsolation conformance test
+ Enabled GRPC conformance profile
+ Enabled HTTPRouteBackendRequestHeaderModifier conformance test
+ Added e2e test for Daemonset mode
+ Fixed OVS scanner wrong license warnings
+ Added e2e test for Gateway with EnvoyProxy
+ Added e2e test for TLS session resumption
+ Added heap profile into benchmark report
+ Added e2e test for RecomputeRoute in ExtAuth
+ Added benchmark memory profiles into report
+ Fixed flaky gateway_with_conflicted_listener_cannot_be_merged e2e test
+ Fixed flaky Zipkin Tracing e2e test
+ Added e2e test for cookie based consistent hash load balancing
+ Added e2e test for load balancing
+ Fixed flaky authorization tests
+ Enabled upgrade test
+ Fixed flaky basic auth e2e test
+ Enabled use-client-protocol e2e test
+ Added performance benchmarking test for 1000 HTTPRoutes
+ Added e2e test for Datadog tracing
+ Added e2e tests for ratelimit invert matching headers
+ Reduced readinessProbe failureThreshold and periodSeconds
+ Bumped go-control-plane to v0.13.1
+ Enabled e2e tests for dual stack
+ Use grafana alloy instead of fluent-bit for e2e tests
+ Push tags without the v prefix for helm charts to support Flux HelmReleases
+ Use a stable label selector when creating Envoy Proxy fleet pods
diff --git a/release-notes/v1.2.1.yaml b/release-notes/v1.2.1.yaml
new file mode 100644
index 00000000000..39ba67fa2ab
--- /dev/null
+++ b/release-notes/v1.2.1.yaml
@@ -0,0 +1,4 @@
+date: November 7, 2024
+
+bug fixes: |
+ Fixed a panic in the provider goroutine when the body in the direct response configuration was nil.
diff --git a/release-notes/v1.2.2.yaml b/release-notes/v1.2.2.yaml
new file mode 100644
index 00000000000..7df6ef2da32
--- /dev/null
+++ b/release-notes/v1.2.2.yaml
@@ -0,0 +1,12 @@
+date: November 28, 2024
+
+bug fixes: |
+ Fixed Envoy rejecting TCP Listeners that have no attached TCPRoutes.
+ Fixed failed to update SecurityPolicy resources with the `backendRef` field specified.
+ Fixed xDS translation failed when oidc tokenEndpoint and jwt remoteJWKS are specified in the same SecurityPolicy and using the same hostname.
+ Fixed frequent 503 errors when connecting to a Service experiencing high Pod churn.
+
+Other changes: |
+ Bump the RateLimit image to 49af5cca.
+ Always use `::` and `IPv4Compact` enabled on dynamic listeners.
+ Use `V4_PREFERRED` instead of `V4_ONLY` by default for the cluster's `DnsLookupFamily`.
diff --git a/release-notes/v1.2.3.yaml b/release-notes/v1.2.3.yaml
new file mode 100644
index 00000000000..ddb7795740e
--- /dev/null
+++ b/release-notes/v1.2.3.yaml
@@ -0,0 +1,9 @@
+date: December 2, 2024
+
+bug fixes: |
+ Disabled the retry policy for the JWT provider to reduce requests sent to the JWKS endpoint. Failed async fetches will retry every 1s.
+ Used a waitGroup instead of an enabled channel in the status updater.
+
+Other changes: |
+ EG Listens on IPv4 by default, but if IPFamily is set to IPv6 or DualStack, it listens on :: and enables ipv4_compat for DualStack.
+ Bumped Gateway API to v1.2.1.
diff --git a/release-notes/v1.2.4.yaml b/release-notes/v1.2.4.yaml
new file mode 100644
index 00000000000..a188d54aec7
--- /dev/null
+++ b/release-notes/v1.2.4.yaml
@@ -0,0 +1,11 @@
+date: December 13, 2024
+
+bug fixes: |
+ Fixed BackendTLSPolicy not supporting the use of a port name as the sectionName in targetRefs.
+ Fixed reference grant from EnvoyExtensionPolicy to the referenced ext-proc backend not being respected.
+ Fixed BackendTrafficPolicy not applying to Gateway Routes when a Route has a Request Timeout defined.
+ Fixed proxies connected to the secondary Envoy Gateway not receiving xDS configuration.
+ Fixed traffic splitting not working when some backends were invalid.
+
+Other changes: |
+ Bumped Envoy to version 1.32.2.
diff --git a/site/assets/icons/logo.svg b/site/assets/icons/logo.svg
index b0e579bd9d4..77ac7ed5386 100644
--- a/site/assets/icons/logo.svg
+++ b/site/assets/icons/logo.svg
@@ -1,170 +1,53 @@
-
-
+
+
\ No newline at end of file
diff --git a/site/assets/scss/_variables_project.scss b/site/assets/scss/_variables_project.scss
index 8c3ce90a2cf..e799cef8e90 100644
--- a/site/assets/scss/_variables_project.scss
+++ b/site/assets/scss/_variables_project.scss
@@ -11,4 +11,13 @@ $dark: #280C53;
// better style when pre inside tab pane
.td-content .highlight pre{
margin-bottom: 1rem !important;
+}
+
+nav.foldable-nav .with-child, nav.foldable-nav .without-child {
+ position: relative;
+ padding-left: 1.0em !important;
+}
+
+nav.foldable-nav .ul-1 .with-child > label:before {
+ padding-left: 0 !important;
}
\ No newline at end of file
diff --git a/site/content/en/contributions/CODEOWNERS.md b/site/content/en/contributions/CODEOWNERS.md
index aeec0b7439b..071532f02c1 100644
--- a/site/content/en/contributions/CODEOWNERS.md
+++ b/site/content/en/contributions/CODEOWNERS.md
@@ -5,7 +5,6 @@ description: "This section includes Maintainers of Envoy Gateway."
## The following maintainers, listed in alphabetical order, own everything
-- @AliceProxy
- @arkodg
- @qicz
- @Xunzhuo
@@ -19,3 +18,4 @@ description: "This section includes Maintainers of Envoy Gateway."
- @LukeShu
- @skriss
- @youngnick
+- @Alice-Lilith
diff --git a/site/content/en/contributions/DEVELOP.md b/site/content/en/contributions/DEVELOP.md
index c953048a4aa..c3d97284c60 100644
--- a/site/content/en/contributions/DEVELOP.md
+++ b/site/content/en/contributions/DEVELOP.md
@@ -156,14 +156,14 @@ The performance and scalability concerns come from several aspects for control-p
- The rate of configuration changes.
The benchmark test is running on a [Kind][Kind] cluster, you can start a Kind cluster and
-run benchmark test on it by executing `make benchmark-test`.
+run benchmark test on it by executing `make benchmark`.
The benchmark report will be included in the release artifacts, you can learn more by downloading
the detailed benchmark report, namely `benchmark_report.zip`.
Here are some brief benchmark reports about Envoy Gateway:
-- It will take up nearly 1.3GiB memory and 11s total CPU time for (1 GatewayClass + 1 Gateway + 500 HTTRoutes) settings
+- It will take up nearly 550MiB memory and 11s total CPU time for (1 GatewayClass + 1 Gateway + 500 HTTRoutes) settings
[Quickstart]: https://github.com/envoyproxy/gateway/blob/main/docs/latest/user/quickstart.md
diff --git a/site/content/en/contributions/RELEASING.md b/site/content/en/contributions/RELEASING.md
index 319bb73d057..2267522dc34 100644
--- a/site/content/en/contributions/RELEASING.md
+++ b/site/content/en/contributions/RELEASING.md
@@ -29,7 +29,13 @@ export GITHUB_REMOTE=origin
```
1. Clone the repo, checkout the `main` branch, ensure it’s up-to-date, and your local branch is clean.
-2. Create a topic branch for adding the release notes and updating the [VERSION][] file with the release version. Refer to previous [release notes][] and [VERSION][] for additional details.
+2. Create a topic branch for adding the release notes and updating the [VERSION][] file with the release version. Refer to previous [release notes][] and [VERSION][] for additional details. The latest changes are already accumulated in the current.yaml file. Copy the content of the current.yaml file to the release notes file and clear the current.yaml file.
+
+ ```shell
+ echo "v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER}" > VERSION
+ ```
+
+ __Note:__ The release candidate version should be in the format `${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER}`.
3. Sign, commit, and push your changes to your fork.
4. Submit a [Pull Request][] to merge the changes into the `main` branch. Do not proceed until your PR has merged and
the [Build and Test][] has successfully completed.
@@ -46,7 +52,8 @@ export GITHUB_REMOTE=origin
git push ${GITHUB_REMOTE} release/v${MAJOR_VERSION}.${MINOR_VERSION}
```
-7. Create a topic branch for updating the Envoy proxy image and Envoy Ratelimit image to the tag supported by the release. Reference [PR #2098][]
+7. Create a topic branch for updating the Envoy proxy image and Envoy Ratelimit image to the tag supported by the release.
+ Please note that the tags should be updated in both the source code and the Helm chart. Reference [PR #2098][]
for additional details on updating the image tag.
8. Sign, commit, and push your changes to your fork.
9. Submit a [Pull Request][] to merge the changes into the `release/v${MAJOR_VERSION}.${MINOR_VERSION}` branch. Do not
@@ -105,49 +112,42 @@ export GITHUB_REMOTE=origin
make docs-release TAG=v${MAJOR_VERSION}.${MINOR_VERSION}.0
```
- 1. Update the `Documentation` referred link on the menu in `site/hugo.toml`:
-
- **DON'T FORGOT TO MOVE IT UNDER `LATEST`**
-
- ```shell
- [[menu.main]]
- name = "Documentation"
- weight = -101
- pre = ""
- url = "/v1.1"
- ```
+ 1. Update `site/layouts/shortcodes/helm-version.html`, add the latest version of the minor release, and update the short code for `{{- with (strings.HasPrefix $pagePrefix "doc") -}}` to the latest minor version.
- 1. Update `site/layouts/shortcodes/helm-version.html` base on latest minor version.
-
```console
{{- $pagePrefix := (index (split $.Page.File.Dir "/") 0) -}}
{{- with (eq $pagePrefix "latest") -}}
{{- "v0.0.0-latest" -}}
{{- end -}}
{{- with (strings.HasPrefix $pagePrefix "v1.1") -}}
- {{- "v1.1.0" -}}
+ {{- "v1.1.3" -}}
+ {{- end -}}
+ {{- with (strings.HasPrefix $pagePrefix "v1.2") -}}
+ {{- "v1.2.0" -}}
{{- end -}}
{{- with (strings.HasPrefix $pagePrefix "doc") -}}
- {{- "v1.1.0" -}}
+ {{- "v1.2.0" -}}
{{- end -}}
```
- 1. Update `site/layouts/shortcodes/yaml-version.html` base on latest minor version.
-
+ 1. Update `site/layouts/shortcodes/yaml-version.html`, add the latest version of the minor release, and update the short code for `{{- with (strings.HasPrefix $pagePrefix "doc") -}}` to the latest minor version.
+
```console
{{- $pagePrefix := (index (split $.Page.File.Dir "/") 0) -}}
{{- with (eq $pagePrefix "latest") -}}
{{- "latest" -}}
{{- end -}}
{{- with (strings.HasPrefix $pagePrefix "v1.1") -}}
- {{- "v1.1.0" -}}
+ {{- "v1.1.3" -}}
+ {{- end -}}
+ {{- with (strings.HasPrefix $pagePrefix "v1.2") -}}
+ {{- "v1.2.0" -}}
{{- end -}}
{{- with (strings.HasPrefix $pagePrefix "doc") -}}
- {{- "v1.1.0" -}}
+ {{- "v1.2.0" -}}
{{- end -}}
```
-
3. Sign, commit, and push your changes to your fork.
4. Submit a [Pull Request][] to merge the changes into the `main` branch. Do not proceed until all your PRs have merged
and the [Build and Test][] has completed for your final PR.
@@ -155,7 +155,7 @@ export GITHUB_REMOTE=origin
5. Checkout the release branch.
```shell
- git checkout -b release/v${MAJOR_VERSION}.${MINOR_VERSION} $GITHUB_REMOTE/release/v${MAJOR_VERSION}.${MINOR_VERSION}
+ git checkout release/v${MAJOR_VERSION}.${MINOR_VERSION} $GITHUB_REMOTE/release/v${MAJOR_VERSION}.${MINOR_VERSION}
```
6. If the tip of the release branch does not match the tip of `main`, perform the following:
@@ -203,12 +203,14 @@ export GITHUB_REMOTE=origin
# Release Announcement
Check out the [v${MAJOR_VERSION}.${MINOR_VERSION} release announcement]
- (https://gateway.envoyproxy.io/releases/v${MAJOR_VERSION}.${MINOR_VERSION}.html) to learn more about the release.
+ (https://gateway.envoyproxy.io/news/releases/notes/v${MAJOR_VERSION}.${MINOR_VERSION}.html) to learn more about the release.
```
+15. Update the `lastVersionTag` in `test/e2e/tests/eg_upgrade.go` to reflect the latest prior release. Refer to [PR #4666] as an example.
+
If you find any bugs in this process, please create an issue.
-## Announce the Release
+### Announce the Release
It's important that the world knows about the release. Use the following steps to announce the release.
@@ -230,6 +232,137 @@ It's important that the world knows about the release. Use the following steps t
Link to the GitHub release and release announcement page that highlights the release.
+## Patch Release
+
+The following steps should be used for creating a patch release.
+
+### Prerequisites
+
+- Permissions to push to the Envoy Gateway repository.
+- A minor release has already been released. Refer to the [Minor Release](#minor-candidate) section for additional details on releasing a minor release.
+
+Set environment variables for use in subsequent steps:
+
+```shell
+export MAJOR_VERSION=1
+export MINOR_VERSION=2
+export PATCH_VERSION=1
+export GITHUB_REMOTE=origin
+```
+
+1. Clone the repo, checkout the `main` branch, ensure it’s up-to-date, and your local branch is clean.
+2. Create a topic branch for adding the release notes.
+
+ 1. Create the release notes. The release note should only include the changes since the last minor or patch release.
+ 1. Create a release announcement. Refer to [PR #635] as an example release announcement.
+ 1. Update `site/layouts/shortcodes/helm-version.html`, update the short code for `{{- with (strings.HasPrefix $pagePrefix "doc") -}}` to the latest patch version. For example:
+
+ ```console
+ {{- $pagePrefix := (index (split $.Page.File.Dir "/") 0) -}}
+ {{- with (eq $pagePrefix "latest") -}}
+ {{- "v0.0.0-latest" -}}
+ {{- end -}}
+ {{- with (strings.HasPrefix $pagePrefix "v1.1") -}}
+ {{- "v1.1.3" -}}
+ {{- end -}}
+ {{- with (strings.HasPrefix $pagePrefix "v1.2") -}}
+ {{- "v1.2.1" -}}
+ {{- end -}}
+ {{- with (strings.HasPrefix $pagePrefix "doc") -}}
+ {{- "v1.2.1" -}}
+ {{- end -}}
+ ```
+
+ 1. Update `site/layouts/shortcodes/yaml-version.html`, update the short code for `{{- with (strings.HasPrefix $pagePrefix "doc") -}}` to the latest patch version. For example:
+
+ ```console
+ {{- $pagePrefix := (index (split $.Page.File.Dir "/") 0) -}}
+ {{- with (eq $pagePrefix "latest") -}}
+ {{- "latest" -}}
+ {{- end -}}
+ {{- with (strings.HasPrefix $pagePrefix "v1.1") -}}
+ {{- "v1.1.3" -}}
+ {{- end -}}
+ {{- with (strings.HasPrefix $pagePrefix "v1.2") -}}
+ {{- "v1.2.1" -}}
+ {{- end -}}
+ {{- with (strings.HasPrefix $pagePrefix "doc") -}}
+ {{- "v1.2.1" -}}
+ {{- end -}}
+ ```
+
+3. Sign, commit, and push your changes to your fork.
+4. Submit a [Pull Request][] to merge the changes into the `main` branch. Do not proceed until all your PRs have merged
+ and the [Build and Test][] has completed for your final PR.
+
+5. Checkout the release branch.
+
+ ```shell
+ git checkout release/v${MAJOR_VERSION}.${MINOR_VERSION} $GITHUB_REMOTE/release/v${MAJOR_VERSION}.${MINOR_VERSION}
+ ```
+
+6. Cherry-pick the release note and release announcement that you created in the previous step to the release branch. The release note will be included in the release artifacts.
+ 1. Create a topic branch from the release branch.
+ 2. Cherry-pick the release note and release announcement commit from `main` to the topic branch.
+ 3. Submit a PR to merge the topic from of your fork into the release branch.
+
+7. Cherry-pick the commits that you want to include in the patch release.
+ 1. Create a topic branch from the release branch.
+ 2. Cherry-pick the commits from `main` that you want to include in the patch release.
+ 3. Run tests locally, e.g. `make lint`.
+ 4. Sign, commit, and push your topic branch to your Envoy Gateway fork.
+ 5. Submit a PR to merge the topic from of your fork into the release branch.
+ 6. Do not proceed until the PR has merged and CI passes for the merged PR.
+ 7. If you are still on your topic branch, change to the release branch:
+
+ ```shell
+ git checkout release/v${MAJOR_VERSION}.${MINOR_VERSION}
+ ```
+
+ 8. Ensure your local release branch is up-to-date:
+
+ ```shell
+ git pull $GITHUB_REMOTE release/v${MAJOR_VERSION}.${MINOR_VERSION}
+ ```
+
+7. Tag the head of your release branch with the release tag. For example:
+
+ ```shell
+ git tag -a v${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION} -m 'Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION} Release'
+ ```
+
+8. Push the tag to the Envoy Gateway repository.
+
+ ```shell
+ git push origin v${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION
+ ```
+
+9. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc.
+10. Confirm that the [release workflow][] completed successfully.
+11. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub.
+12. Confirm that the [release][] was created.
+13. Confirm that the steps in the [Quickstart][] work as expected.
+14. [Generate][] the GitHub changelog and include the following text at the beginning of the release page:
+
+ ```console
+ # Release Announcement
+
+ Check out the [v${MAJOR_VERSION}.${MINOR_VERSION}.${MINOR_VERSION} release announcement]
+ (https://gateway.envoyproxy.io/news/releases/notes/v${MAJOR_VERSION}.${MINOR_VERSION}.${MINOR_VERSION}.html) to learn more about the release.
+ ```
+
+15. If this patch release is the latest release, update the `lastVersionTag` in `test/e2e/tests/eg_upgrade.go` to reflect the latest prior release. Refer to [PR #4666] as an example.
+
+### Announce the Release
+
+It's important that the world knows about the release. Use the following steps to announce the release.
+
+1. Set the release information in the Envoy Gateway Slack channel. For example:
+
+ ```shell
+ Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION} has been released: https://github.com/envoyproxy/gateway/releases/tag/v${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}
+ ```
+
[release notes]: https://github.com/envoyproxy/gateway/tree/main/release-notes
[Pull Request]: https://github.com/envoyproxy/gateway/pulls
[Quickstart]: https://github.com/envoyproxy/gateway/blob/main/docs/user/quickstart.md
@@ -242,4 +375,5 @@ It's important that the world knows about the release. Use the following steps t
[PR #635]: https://github.com/envoyproxy/gateway/pull/635
[PR #2098]: https://github.com/envoyproxy/gateway/pull/2098
[PR #1002]: https://github.com/envoyproxy/gateway/pull/1002
+[PR #4666]: https://github.com/envoyproxy/gateway/pull/4666
[VERSION]: https://github.com/envoyproxy/gateway/blob/main/VERSION
diff --git a/site/content/en/contributions/design/envoy-extension-policy.md b/site/content/en/contributions/design/envoy-extension-policy.md
index 67af7cd6ef1..9ecf2598829 100644
--- a/site/content/en/contributions/design/envoy-extension-policy.md
+++ b/site/content/en/contributions/design/envoy-extension-policy.md
@@ -96,12 +96,6 @@ spec:
response:
headers: SKIP
body: STREAMED
- attributes:
- request:
- - xds.route_metadata
- - connection.requested_server_name
- response:
- - request.path
messageTimeout: 5s
targetRef:
group: gateway.networking.k8s.io
diff --git a/site/content/en/contributions/design/metadata.md b/site/content/en/contributions/design/metadata.md
index 143f5b2797d..f6564f3ccd5 100644
--- a/site/content/en/contributions/design/metadata.md
+++ b/site/content/en/contributions/design/metadata.md
@@ -25,7 +25,27 @@ Future enhancements may include:
## Translation
-Envoy Gateway uses the following namespace for envoy resource metadata: `io.envoyproxy.gateway.metadata`. For example, an envoy [route][] resource may have the following metadata structure:
+Envoy Gateway uses the following namespace for envoy resource metadata: `gateway.envoyproxy.io/`. For example, an envoy [route][] resource may have the following metadata structure:
+
+Kubernetes resource:
+
+```yaml
+kind: HTTPRoute
+apiVersion: gateway.networking.k8s.io/v1
+metadata:
+ annotations:
+ gateway.envoyproxy.io/foo: bar
+ name: myroute
+ namespace: gateway-conformance-infra
+spec:
+ rules:
+ matches:
+ - path:
+ type: PathPrefix
+ value: /mypath
+```
+
+Metadata structure:
```yaml
name: httproute/gateway-conformance-infra/myroute/rule/0/match/0/*
diff --git a/site/content/en/contributions/roadmap.md b/site/content/en/contributions/roadmap.md
index 955af2a9623..54b808587f9 100644
--- a/site/content/en/contributions/roadmap.md
+++ b/site/content/en/contributions/roadmap.md
@@ -63,6 +63,10 @@ contributing to the project.
- Add TrafficPolicy APIs for advanced features [Issue #1492][1492].
- Envoy Gateway meets readiness criteria [Issue #1160][1160].
+### [v1.0.0][v1.0.0]: Envoy Gateway goes GA
+
+Visit the [milestones][milestones] page to learn more about the future roadmap.
+
[issue]: https://github.com/envoyproxy/gateway/issues
[meeting]: https://docs.google.com/document/d/1leqwsHX8N-XxNEyTflYjRur462ukFxd19Rnk3Uzy55I/edit?usp=sharing
[pr]: https://github.com/envoyproxy/gateway/compare
@@ -72,6 +76,7 @@ contributing to the project.
[v0.4.0]: https://github.com/envoyproxy/gateway/milestone/12
[v0.5.0]: https://github.com/envoyproxy/gateway/milestone/13
[v0.6.0]: https://github.com/envoyproxy/gateway/milestone/15
+[v1.0.0]: https://github.com/envoyproxy/gateway/milestone/18
[17]: https://github.com/envoyproxy/gateway/issues/17
[20]: https://github.com/envoyproxy/gateway/issues/20
[24]: https://github.com/envoyproxy/gateway/issues/24
diff --git a/site/content/en/docs/api/extension_types.md b/site/content/en/docs/api/extension_types.md
index 02f5755075d..a519fc34ea7 100644
--- a/site/content/en/docs/api/extension_types.md
+++ b/site/content/en/docs/api/extension_types.md
@@ -15,19 +15,14 @@ API group.
### Resource Types
- [Backend](#backend)
-- [BackendList](#backendlist)
- [BackendTrafficPolicy](#backendtrafficpolicy)
-- [BackendTrafficPolicyList](#backendtrafficpolicylist)
- [ClientTrafficPolicy](#clienttrafficpolicy)
-- [ClientTrafficPolicyList](#clienttrafficpolicylist)
- [EnvoyExtensionPolicy](#envoyextensionpolicy)
-- [EnvoyExtensionPolicyList](#envoyextensionpolicylist)
- [EnvoyGateway](#envoygateway)
- [EnvoyPatchPolicy](#envoypatchpolicy)
-- [EnvoyPatchPolicyList](#envoypatchpolicylist)
- [EnvoyProxy](#envoyproxy)
+- [HTTPRouteFilter](#httproutefilter)
- [SecurityPolicy](#securitypolicy)
-- [SecurityPolicyList](#securitypolicylist)
@@ -68,7 +63,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs references a Kubernetes object that represents the gRPC service to which the access logs will be sent. Currently only Service is supported. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `logName` | _string_ | false | LogName defines the friendly name of the access log to be returned in StreamAccessLogsMessage.Identifier. This allows the access log server to differentiate between different access logs coming from the same Envoy. |
| `type` | _[ALSEnvoyProxyAccessLogType](#alsenvoyproxyaccesslogtype)_ | true | Type defines the type of accesslog. Supported types are "HTTP" and "TCP". |
| `http` | _[ALSEnvoyProxyHTTPAccessLogConfig](#alsenvoyproxyhttpaccesslogconfig)_ | false | HTTP defines additional configuration specific to HTTP access logs. |
@@ -124,6 +121,7 @@ _Appears in:_
| `type` | _[ActiveHealthCheckerType](#activehealthcheckertype)_ | true | Type defines the type of health checker. |
| `http` | _[HTTPActiveHealthChecker](#httpactivehealthchecker)_ | false | HTTP defines the configuration of http health checker. It's required while the health checker type is HTTP. |
| `tcp` | _[TCPActiveHealthChecker](#tcpactivehealthchecker)_ | false | TCP defines the configuration of tcp health checker. It's required while the health checker type is TCP. |
+| `grpc` | _[GRPCActiveHealthChecker](#grpcactivehealthchecker)_ | false | GRPC defines the configuration of the GRPC health checker. It's optional, and can only be used if the specified type is GRPC. |
#### ActiveHealthCheckPayload
@@ -171,6 +169,7 @@ _Appears in:_
| ----- | ----------- |
| `HTTP` | ActiveHealthCheckerTypeHTTP defines the HTTP type of health checking. |
| `TCP` | ActiveHealthCheckerTypeTCP defines the TCP type of health checking. |
+| `GRPC` | ActiveHealthCheckerTypeGRPC defines the GRPC type of health checking. |
#### AppProtocolType
@@ -234,9 +233,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `name` | _string_ | false | Name is a user-friendly name for the rule. If not specified, Envoy Gateway will generate a unique name for the rule.n |
+| `name` | _string_ | false | Name is a user-friendly name for the rule. If not specified, Envoy Gateway will generate a unique name for the rule. |
| `action` | _[AuthorizationAction](#authorizationaction)_ | true | Action defines the action to be taken if the rule matches. |
-| `principal` | _[Principal](#principal)_ | true | Principal specifies the client identity of a request. |
+| `principal` | _[Principal](#principal)_ | true | Principal specifies the client identity of a request. If there are multiple principal types, all principals must match for the rule to match. For example, if there are two principals: one for client IP and one for JWT claim, the rule will match only if both the client IP and the JWT claim match. |
#### BackOffPolicy
@@ -261,8 +260,7 @@ _Appears in:_
Backend allows the user to configure the endpoints of a backend and
the behavior of the connection from Envoy Proxy to the backend.
-_Appears in:_
-- [BackendList](#backendlist)
+
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -273,6 +271,31 @@ _Appears in:_
| `status` | _[BackendStatus](#backendstatus)_ | true | Status defines the current status of Backend. |
+#### BackendCluster
+
+
+
+BackendCluster contains all the configuration required for configuring access
+to a backend. This can include multiple endpoints, and settings that apply for
+managing the connection to all these endpoints.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OIDCProvider](#oidcprovider)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+
+
@@ -285,10 +308,11 @@ BackendConnection allows users to configure connection-level settings of backend
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `bufferLimit` | _[Quantity](#quantity)_ | false | BufferLimit Soft limit on size of the cluster’s connections read and write buffers. If unspecified, an implementation defined default is applied (32768 bytes). For example, 20Mi, 1Gi, 256Ki etc. Note: that when the suffix is not provided, the value is interpreted as bytes. |
+| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit Soft limit on size of the cluster’s connections read and write buffers. BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. If unspecified, an implementation defined default is applied (32768 bytes). For example, 20Mi, 1Gi, 256Ki etc. Note: that when the suffix is not provided, the value is interpreted as bytes. |
#### BackendEndpoint
@@ -305,26 +329,10 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `fqdn` | _[FQDNEndpoint](#fqdnendpoint)_ | false | FQDN defines a FQDN endpoint |
-| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Currently, only IPv4 Addresses are supported. |
+| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Supports both IPv4 and IPv6 addresses. |
| `unix` | _[UnixSocket](#unixsocket)_ | false | Unix defines the unix domain socket endpoint |
-#### BackendList
-
-
-
-BackendList contains a list of Backend resources.
-
-
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`BackendList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[Backend](#backend) array_ | true | |
-
-
#### BackendRef
@@ -333,9 +341,11 @@ BackendRef defines how an ObjectReference that is specific to BackendRef.
_Appears in:_
- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [BackendCluster](#backendcluster)
- [ExtProc](#extproc)
- [GRPCExtAuthService](#grpcextauthservice)
- [HTTPExtAuthService](#httpextauthservice)
+- [OIDCProvider](#oidcprovider)
- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
- [TracingProvider](#tracingprovider)
@@ -347,6 +357,7 @@ _Appears in:_
| `name` | _[ObjectName](#objectname)_ | true | Name is the name of the referent. |
| `namespace` | _[Namespace](#namespace)_ | false | Namespace is the namespace of the backend. When unspecified, the local namespace is inferred.
Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.
Support: Core |
| `port` | _[PortNumber](#portnumber)_ | false | Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. |
+| `fallback` | _boolean_ | false | Fallback indicates whether the backend is designated as a fallback. Multiple fallback backends can be configured. It is highly recommended to configure active or passive health checks to ensure that failover can be detected when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again. The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when the health of the active backends falls below 72%. |
#### BackendSpec
@@ -362,6 +373,7 @@ _Appears in:_
| --- | --- | --- | --- |
| `endpoints` | _[BackendEndpoint](#backendendpoint) array_ | true | Endpoints defines the endpoints to be used when connecting to the backend. |
| `appProtocols` | _[AppProtocolType](#appprotocoltype) array_ | false | AppProtocols defines the application protocols to be supported when connecting to the backend. |
+| `fallback` | _boolean_ | false | Fallback indicates whether the backend is designated as a fallback. It is highly recommended to configure active or passive health checks to ensure that failover can be detected when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again. The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when the health of the active backends falls below 72%. |
#### BackendStatus
@@ -405,8 +417,7 @@ _Appears in:_
BackendTrafficPolicy allows the user to configure the behavior of the connection
between the Envoy Proxy listener and the backend service.
-_Appears in:_
-- [BackendTrafficPolicyList](#backendtrafficpolicylist)
+
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -417,24 +428,6 @@ _Appears in:_
| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | status defines the current status of BackendTrafficPolicy. |
-
-
-#### BackendTrafficPolicyList
-
-
-
-BackendTrafficPolicyList contains a list of BackendTrafficPolicy resources.
-
-
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`BackendTrafficPolicyList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[BackendTrafficPolicy](#backendtrafficpolicy) array_ | true | |
-
-
#### BackendTrafficPolicySpec
@@ -449,17 +442,20 @@ _Appears in:_
| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to. This policy and the TargetRef MUST be in the same namespace for this Policy to have effect
Deprecated: use targetRefs/targetSelectors instead |
| `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy is being attached to. |
| `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels |
-| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. |
-| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints |
+| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints. Defaults to `LeastRequest`. |
+| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. |
| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection. Disabled by default. |
| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. |
-| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to inject delays and abort requests to mimic failure scenarios such as service failures and overloads |
| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests. If not set, circuit breakers will be enabled with the default thresholds |
-| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
-| `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using the same HTTP protocol that the incoming request used. Defaults to false, which means that Envoy will use the protocol indicated by the attached BackendRef. |
| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. |
| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. |
+| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. |
+| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. |
+| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. |
+| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to inject delays and abort requests to mimic failure scenarios such as service failures and overloads |
+| `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using the same HTTP protocol that the incoming request used. Defaults to false, which means that Envoy will use the protocol indicated by the attached BackendRef. |
+| `responseOverride` | _[ResponseOverride](#responseoverride) array_ | false | ResponseOverride defines the configuration to override specific responses with a custom one. If multiple configurations are specified, the first one to match wins. |
#### BasicAuth
@@ -473,7 +469,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `users` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the username-password pairs in htpasswd format, used to verify user credentials in the "Authorization" header.
This is an Opaque secret. The username-password pairs should be stored in the key ".htpasswd". As the key name indicates, the value needs to be the htpasswd format, for example: "user1:{SHA}hashed_user1_password". Right now, only SHA hash algorithm is supported. Reference to https://httpd.apache.org/docs/2.4/programs/htpasswd.html for more details.
Note: The secret must be in the same namespace as the SecurityPolicy. |
+| `users` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the username-password pairs in htpasswd format, used to verify user credentials in the "Authorization" header.
This is an Opaque secret. The username-password pairs should be stored in the key ".htpasswd". As the key name indicates, the value needs to be the htpasswd format, for example: "user1:\{SHA\}hashed_user1_password". Right now, only SHA hash algorithm is supported. Reference to https://httpd.apache.org/docs/2.4/programs/htpasswd.html for more details.
Note: The secret must be in the same namespace as the SecurityPolicy. |
#### BootstrapType
@@ -489,6 +485,7 @@ _Appears in:_
| ----- | ----------- |
| `Merge` | Merge merges the provided bootstrap with the default one. The provided bootstrap can add or override a value within a map, or add a new value to a list. Please note that the provided bootstrap can't override a value within a list. |
| `Replace` | Replace replaces the default bootstrap with the provided one. |
+| `JSONPatch` | JSONPatch applies the provided JSONPatches to the default bootstrap. |
#### CIDR
@@ -500,6 +497,7 @@ A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address
_Appears in:_
- [Principal](#principal)
+- [XForwardedForSettings](#xforwardedforsettings)
@@ -514,12 +512,12 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `allowOrigins` | _[Origin](#origin) array_ | true | AllowOrigins defines the origins that are allowed to make requests. |
-| `allowMethods` | _string array_ | true | AllowMethods defines the methods that are allowed to make requests. |
-| `allowHeaders` | _string array_ | true | AllowHeaders defines the headers that are allowed to be sent with requests. |
-| `exposeHeaders` | _string array_ | true | ExposeHeaders defines the headers that can be exposed in the responses. |
-| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | MaxAge defines how long the results of a preflight request can be cached. |
-| `allowCredentials` | _boolean_ | true | AllowCredentials indicates whether a request can include user credentials like cookies, authentication headers, or TLS client certificates. |
+| `allowOrigins` | _[Origin](#origin) array_ | false | AllowOrigins defines the origins that are allowed to make requests. It specifies the allowed origins in the Access-Control-Allow-Origin CORS response header. The value "*" allows any origin to make requests. |
+| `allowMethods` | _string array_ | false | AllowMethods defines the methods that are allowed to make requests. It specifies the allowed methods in the Access-Control-Allow-Methods CORS response header.. The value "*" allows any method to be used. |
+| `allowHeaders` | _string array_ | false | AllowHeaders defines the headers that are allowed to be sent with requests. It specifies the allowed headers in the Access-Control-Allow-Headers CORS response header.. The value "*" allows any header to be sent. |
+| `exposeHeaders` | _string array_ | false | ExposeHeaders defines which response headers should be made accessible to scripts running in the browser. It specifies the headers in the Access-Control-Expose-Headers CORS response header.. The value "*" allows any header to be exposed. |
+| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MaxAge defines how long the results of a preflight request can be cached. It specifies the value in the Access-Control-Max-Age CORS response header.. |
+| `allowCredentials` | _boolean_ | false | AllowCredentials indicates whether a request can include user credentials like cookies, authentication headers, or TLS client certificates. It specifies the value in the Access-Control-Allow-Credentials CORS response header. |
#### CircuitBreaker
@@ -530,6 +528,7 @@ CircuitBreaker defines the Circuit Breaker configuration.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -567,7 +566,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `connectionLimit` | _[ConnectionLimit](#connectionlimit)_ | false | ConnectionLimit defines limits related to connections |
-| `bufferLimit` | _[Quantity](#quantity)_ | false | BufferLimit provides configuration for the maximum buffer size in bytes for each incoming connection. For example, 20Mi, 1Gi, 256Ki etc. Note that when the suffix is not provided, the value is interpreted as bytes. Default: 32768 bytes. |
+| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit provides configuration for the maximum buffer size in bytes for each incoming connection. BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. For example, 20Mi, 1Gi, 256Ki etc. Note that when the suffix is not provided, the value is interpreted as bytes. Default: 32768 bytes. |
#### ClientIPDetectionSettings
@@ -603,6 +602,7 @@ _Appears in:_
| `ecdhCurves` | _string array_ | false | ECDHCurves specifies the set of supported ECDH curves. In non-FIPS Envoy Proxy builds the default curves are: - X25519 - P-256 In builds using BoringSSL FIPS the default curve is: - P-256 |
| `signatureAlgorithms` | _string array_ | false | SignatureAlgorithms specifies which signature algorithms the listener should support. |
| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be exposed by the listener. By default h2 and http/1.1 are enabled. Supported values are: - http/1.0 - http/1.1 - h2 |
+| `session` | _[Session](#session)_ | false | Session defines settings related to TLS session management. |
#### ClientTimeout
@@ -627,8 +627,7 @@ _Appears in:_
ClientTrafficPolicy allows the user to configure the behavior of the connection
between the downstream client and Envoy Proxy listener.
-_Appears in:_
-- [ClientTrafficPolicyList](#clienttrafficpolicylist)
+
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -639,22 +638,6 @@ _Appears in:_
| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of ClientTrafficPolicy. |
-#### ClientTrafficPolicyList
-
-
-
-ClientTrafficPolicyList contains a list of ClientTrafficPolicy resources.
-
-
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`ClientTrafficPolicyList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[ClientTrafficPolicy](#clienttrafficpolicy) array_ | true | |
-
-
#### ClientTrafficPolicySpec
@@ -700,6 +683,39 @@ _Appears in:_
| `caCertificateRefs` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference) array_ | false | CACertificateRefs contains one or more references to Kubernetes objects that contain TLS certificates of the Certificate Authorities that can be used as a trust anchor to validate the certificates presented by the client.
A single reference to a Kubernetes ConfigMap or a Kubernetes Secret, with the CA certificate in a key named `ca.crt` is currently supported.
References to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. |
+#### ClusterSettings
+
+
+
+ClusterSettings provides the various knobs that can be set to control how traffic to a given
+backend will be configured.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [BackendCluster](#backendcluster)
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OIDCProvider](#oidcprovider)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints. Defaults to `LeastRequest`. |
+| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
+| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. |
+| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection. Disabled by default. |
+| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. |
+| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests. If not set, circuit breakers will be enabled with the default thresholds |
+| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. |
+| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. |
+| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. |
+| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. |
+
+
#### Compression
@@ -739,7 +755,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `value` | _integer_ | true | Value of the maximum concurrent connections limit. When the limit is reached, incoming connections will be closed after the CloseDelay duration. Default: unlimited. |
+| `value` | _integer_ | true | Value of the maximum concurrent connections limit. When the limit is reached, incoming connections will be closed after the CloseDelay duration. |
| `closeDelay` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | CloseDelay defines the delay to use before closing connections that are rejected once the limit value is reached. Default: none. |
@@ -812,6 +828,52 @@ _Appears in:_
| `failClosed` | _boolean_ | false | FailClosed is a switch used to control the flow of traffic when client IP detection fails. If set to true, the listener will respond with 403 Forbidden when the client IP address cannot be determined. |
+#### CustomResponse
+
+
+
+CustomResponse defines the configuration for returning a custom response.
+
+_Appears in:_
+- [ResponseOverride](#responseoverride)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `contentType` | _string_ | false | Content Type of the response. This will be set in the Content-Type header. |
+| `body` | _[CustomResponseBody](#customresponsebody)_ | true | Body of the Custom Response |
+
+
+#### CustomResponseBody
+
+
+
+CustomResponseBody
+
+_Appears in:_
+- [CustomResponse](#customresponse)
+- [HTTPDirectResponseFilter](#httpdirectresponsefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[ResponseValueType](#responsevaluetype)_ | true | Type is the type of method to use to read the body value. Valid values are Inline and ValueRef, default is Inline. |
+| `inline` | _string_ | false | Inline contains the value as an inline string. |
+| `valueRef` | _[LocalObjectReference](#localobjectreference)_ | false | ValueRef contains the contents of the body specified as a local object reference. Only a reference to ConfigMap is supported.
The value of key `response.body` in the ConfigMap will be used as the response body. If the key is not found, the first value in the ConfigMap will be used. |
+
+
+#### CustomResponseMatch
+
+
+
+CustomResponseMatch defines the configuration for matching a user response to return a custom one.
+
+_Appears in:_
+- [ResponseOverride](#responseoverride)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `statusCodes` | _[StatusCodeMatch](#statuscodematch) array_ | true | Status code to match on. The match evaluates to true if any of the matches are successful. |
+
+
#### CustomTag
@@ -845,53 +907,52 @@ _Appears in:_
| `RequestHeader` | CustomTagTypeRequestHeader adds value from request header to each span. |
-#### EnvironmentCustomTag
+#### DNS
+
-EnvironmentCustomTag adds value from environment variable to each span.
_Appears in:_
-- [CustomTag](#customtag)
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `name` | _string_ | true | Name defines the name of the environment variable which to extract the value from. |
-| `defaultValue` | _string_ | false | DefaultValue defines the default value to use if the environment variable is not set. |
+| `dnsRefreshRate` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | DNSRefreshRate specifies the rate at which DNS records should be refreshed. Defaults to 30 seconds. |
+| `respectDnsTtl` | _boolean_ | true | RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. Defaults to true. |
-#### EnvoyExtensionPolicy
+#### EnvironmentCustomTag
-EnvoyExtensionPolicy allows the user to configure various envoy extensibility options for the Gateway.
+EnvironmentCustomTag adds value from environment variable to each span.
_Appears in:_
-- [EnvoyExtensionPolicyList](#envoyextensionpolicylist)
+- [CustomTag](#customtag)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`EnvoyExtensionPolicy`
-| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `spec` | _[EnvoyExtensionPolicySpec](#envoyextensionpolicyspec)_ | true | Spec defines the desired state of EnvoyExtensionPolicy. |
-| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of EnvoyExtensionPolicy. |
+| `name` | _string_ | true | Name defines the name of the environment variable which to extract the value from. |
+| `defaultValue` | _string_ | false | DefaultValue defines the default value to use if the environment variable is not set. |
-#### EnvoyExtensionPolicyList
+#### EnvoyExtensionPolicy
-EnvoyExtensionPolicyList contains a list of EnvoyExtensionPolicy resources.
+EnvoyExtensionPolicy allows the user to configure various envoy extensibility options for the Gateway.
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`EnvoyExtensionPolicyList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[EnvoyExtensionPolicy](#envoyextensionpolicy) array_ | true | |
+| `kind` | _string_ | |`EnvoyExtensionPolicy`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[EnvoyExtensionPolicySpec](#envoyextensionpolicyspec)_ | true | Spec defines the desired state of EnvoyExtensionPolicy. |
+| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of EnvoyExtensionPolicy. |
#### EnvoyExtensionPolicySpec
@@ -930,11 +991,13 @@ _Appears in:_
| `envoy.filters.http.basic_auth` | EnvoyFilterBasicAuth defines the Envoy HTTP basic authentication filter. |
| `envoy.filters.http.oauth2` | EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter. |
| `envoy.filters.http.jwt_authn` | EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter. |
+| `envoy.filters.http.stateful_session` | EnvoyFilterSessionPersistence defines the Envoy HTTP session persistence filter. |
| `envoy.filters.http.ext_proc` | EnvoyFilterExtProc defines the Envoy HTTP external process filter. |
| `envoy.filters.http.wasm` | EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter. |
| `envoy.filters.http.rbac` | EnvoyFilterRBAC defines the Envoy RBAC filter. |
| `envoy.filters.http.local_ratelimit` | EnvoyFilterLocalRateLimit defines the Envoy HTTP local rate limit filter. |
| `envoy.filters.http.ratelimit` | EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter. |
+| `envoy.filters.http.custom_response` | EnvoyFilterCustomResponse defines the Envoy HTTP custom response filter. |
| `envoy.filters.http.router` | EnvoyFilterRouter defines the Envoy HTTP router filter. |
@@ -1004,7 +1067,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `resource` | _[EnvoyGatewayResourceProvider](#envoygatewayresourceprovider)_ | true | Resource defines the desired resource provider. This provider is used to specify the provider to be used to retrieve the resource configurations such as Gateway API resources |
-| `infrastructure` | _[EnvoyGatewayInfrastructureProvider](#envoygatewayinfrastructureprovider)_ | true | Infrastructure defines the desired infrastructure provider. This provider is used to specify the provider to be used to provide an environment to deploy the out resources like the Envoy Proxy data plane. |
+| `infrastructure` | _[EnvoyGatewayInfrastructureProvider](#envoygatewayinfrastructureprovider)_ | false | Infrastructure defines the desired infrastructure provider. This provider is used to specify the provider to be used to provide an environment to deploy the out resources like the Envoy Proxy data plane.
Infrastructure is optional, if provider is not specified, No infrastructure provider is available. |
#### EnvoyGatewayFileResourceProvider
@@ -1018,7 +1081,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `paths` | _string array_ | true | Paths are the paths to a directory or file containing the resource configuration. Recursive sub directories are not currently supported. |
+| `paths` | _string array_ | true | Paths are the paths to a directory or file containing the resource configuration. Recursive subdirectories are not currently supported. |
#### EnvoyGatewayHostInfrastructureProvider
@@ -1176,9 +1239,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `type` | _[ProviderType](#providertype)_ | true | Type is the type of provider to use. Supported types are "Kubernetes". |
+| `type` | _[ProviderType](#providertype)_ | true | Type is the type of provider to use. Supported types are "Kubernetes", "Custom". |
| `kubernetes` | _[EnvoyGatewayKubernetesProvider](#envoygatewaykubernetesprovider)_ | false | Kubernetes defines the configuration of the Kubernetes provider. Kubernetes provides runtime configuration via the Kubernetes API. |
-| `custom` | _[EnvoyGatewayCustomProvider](#envoygatewaycustomprovider)_ | false | Custom defines the configuration for the Custom provider. This provider allows you to define a specific resource provider and a infrastructure provider. |
+| `custom` | _[EnvoyGatewayCustomProvider](#envoygatewaycustomprovider)_ | false | Custom defines the configuration for the Custom provider. This provider allows you to define a specific resource provider and an infrastructure provider. |
#### EnvoyGatewayResourceProvider
@@ -1257,8 +1320,7 @@ _Appears in:_
EnvoyPatchPolicy allows the user to modify the generated Envoy xDS
resources by Envoy Gateway using this patch API
-_Appears in:_
-- [EnvoyPatchPolicyList](#envoypatchpolicylist)
+
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -1269,22 +1331,6 @@ _Appears in:_
| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of EnvoyPatchPolicy. |
-#### EnvoyPatchPolicyList
-
-
-
-EnvoyPatchPolicyList contains a list of EnvoyPatchPolicy resources.
-
-
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`EnvoyPatchPolicyList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[EnvoyPatchPolicy](#envoypatchpolicy) array_ | true | |
-
-
#### EnvoyPatchPolicySpec
@@ -1388,8 +1434,9 @@ _Appears in:_
| `extraArgs` | _string array_ | false | ExtraArgs defines additional command line options that are provided to Envoy. More info: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#command-line-options Note: some command line options are used internally(e.g. --log-level) so they cannot be provided here. |
| `mergeGateways` | _boolean_ | false | MergeGateways defines if Gateway resources should be merged onto the same Envoy Proxy Infrastructure. Setting this field to true would merge all Gateway Listeners under the parent Gateway Class. This means that the port, protocol and hostname tuple must be unique for every listener. If a duplicate listener is detected, the newer listener (based on timestamp) will be rejected and its status will be updated with a "Accepted=False" condition. |
| `shutdown` | _[ShutdownConfig](#shutdownconfig)_ | false | Shutdown defines configuration for graceful envoy shutdown process. |
-| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. The FilterPosition in the list will be applied in the order they are defined. If unspecified, the default filter order is applied. Default filter order is:
- envoy.filters.http.health_check
- envoy.filters.http.fault
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.router
Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. |
+| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. The FilterPosition in the list will be applied in the order they are defined. If unspecified, the default filter order is applied. Default filter order is:
- envoy.filters.http.health_check
- envoy.filters.http.fault
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.custom_response
- envoy.filters.http.router
Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. |
| `backendTLS` | _[BackendTLSConfig](#backendtlsconfig)_ | false | BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends. These settings are applied on backends for which TLS policies are specified. |
+| `ipFamily` | _[IPFamily](#ipfamily)_ | false | IPFamily specifies the IP family for the EnvoyProxy fleet. This setting only affects the Gateway listener port and does not impact other aspects of the Envoy proxy configuration. If not specified, the system will operate as follows: - It defaults to IPv4 only. - IPv6 and dual-stack environments are not supported in this default configuration. Note: To enable IPv6 or dual-stack functionality, explicit configuration is required. |
#### EnvoyProxyStatus
@@ -1436,6 +1483,7 @@ _Appears in:_
| `http` | _[HTTPExtAuthService](#httpextauthservice)_ | true | HTTP defines the HTTP External Authorization service. Either GRPCService or HTTPService must be specified, and only one of them can be provided. |
| `headersToExtAuth` | _string array_ | false | HeadersToExtAuth defines the client request headers that will be included in the request to the external authorization service. Note: If not specified, the default behavior for gRPC and HTTP external authorization services is different due to backward compatibility reasons. All headers will be included in the check request to a gRPC authorization server. Only the following headers will be included in the check request to an HTTP authorization server: Host, Method, Path, Content-Length, and Authorization. And these headers will always be included to the check request to an HTTP authorization server by default, no matter whether they are specified in HeadersToExtAuth or not. |
| `failOpen` | _boolean_ | false | FailOpen is a switch used to control the behavior when a response from the External Authorization service cannot be obtained. If FailOpen is set to true, the system allows the traffic to pass through. Otherwise, if it is set to false or not set (defaulting to false), the system blocks the traffic and returns a HTTP 5xx error, reflecting a fail-closed approach. This setting determines whether to prioritize accessibility over strict security in case of authorization service failure. |
+| `recomputeRoute` | _boolean_ | false | RecomputeRoute clears the route cache and recalculates the routing decision. This field must be enabled if the headers added or modified by the ExtAuth are used for route matching decisions. If the recomputation selects a new route, features targeting the new matched route will be applied. |
#### ExtProc
@@ -1449,7 +1497,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs defines the configuration of the external processing service |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `messageTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | MessageTimeout is the timeout for a response to be returned from the external processor Default: 200ms |
| `failOpen` | _boolean_ | false | FailOpen defines if requests or responses that cannot be processed due to connectivity to the external processor are terminated or passed-through. Default: false |
| `processingMode` | _[ExtProcProcessingMode](#extprocprocessingmode)_ | false | ProcessingMode defines how request and response body is processed Default: header and body are not sent to the external processor |
@@ -1548,7 +1598,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `fqdn` | _[FQDNEndpoint](#fqdnendpoint)_ | false | FQDN defines a FQDN endpoint |
-| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Currently, only IPv4 Addresses are supported. |
+| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Supports both IPv4 and IPv6 addresses. |
| `unix` | _[UnixSocket](#unixsocket)_ | false | Unix defines the unix domain socket endpoint |
| `host` | _string_ | false | Host define the extension service hostname. Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix) |
| `port` | _integer_ | false | Port defines the port the extension service is exposed on. Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix) |
@@ -1663,6 +1713,20 @@ _Appears in:_
| `after` | _[EnvoyFilter](#envoyfilter)_ | true | After defines the filter that should come after the filter. Only one of Before or After must be set. |
+#### GRPCActiveHealthChecker
+
+
+
+GRPCActiveHealthChecker defines the settings of the GRPC health check.
+
+_Appears in:_
+- [ActiveHealthCheck](#activehealthcheck)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `service` | _string_ | false | Service to send in the health check request. If this is not specified, then the health check request applies to the entire server and not to a specific service. |
+
+
#### GRPCExtAuthService
@@ -1676,8 +1740,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now.
Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
#### Gateway
@@ -1773,16 +1838,19 @@ _Appears in:_
-HTTP2Settings provides HTTP/2 configuration on the listener.
+HTTP2Settings provides HTTP/2 configuration for listeners and backends.
_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `initialStreamWindowSize` | _[Quantity](#quantity)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams. If not set, the default value is 64 KiB(64*1024). |
-| `initialConnectionWindowSize` | _[Quantity](#quantity)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. If not set, the default value is 1 MiB. |
+| `initialStreamWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams. If not set, the default value is 64 KiB(64*1024). |
+| `initialConnectionWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. If not set, the default value is 1 MiB. |
| `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. If not set, the default value is 100. |
+| `onInvalidMessage` | _[InvalidMessageAction](#invalidmessageaction)_ | false | OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error It's recommended for L2 Envoy deployments to set this value to TerminateStream. https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two Default: TerminateConnection |
#### HTTP3Settings
@@ -1828,6 +1896,22 @@ _Appears in:_
| `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | IdleTimeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. Default: 1 hour. |
+#### HTTPDirectResponseFilter
+
+
+
+HTTPDirectResponseFilter defines the configuration to return a fixed response.
+
+_Appears in:_
+- [HTTPRouteFilterSpec](#httproutefilterspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `contentType` | _string_ | false | Content Type of the response. This will be set in the Content-Type header. |
+| `body` | _[CustomResponseBody](#customresponsebody)_ | false | Body of the Response |
+| `statusCode` | _integer_ | false | Status Code of the HTTP response If unset, defaults to 200. |
+
+
#### HTTPExtAuthService
@@ -1839,12 +1923,104 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now.
Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `path` | _string_ | true | Path is the path of the HTTP External Authorization service. If path is specified, the authorization request will be sent to that path, or else the authorization request will be sent to the root path. |
| `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added to the original client request before sending it to the backend server. Note that coexisting headers will be overridden. If not specified, no authorization response headers will be added to the original client request. |
+#### HTTPHostnameModifier
+
+
+
+
+
+_Appears in:_
+- [HTTPURLRewriteFilter](#httpurlrewritefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[HTTPHostnameModifierType](#httphostnamemodifiertype)_ | true | |
+| `header` | _string_ | false | Header is the name of the header whose value would be used to rewrite the Host header |
+
+
+#### HTTPHostnameModifierType
+
+_Underlying type:_ _string_
+
+HTTPPathModifierType defines the type of Hostname rewrite.
+
+_Appears in:_
+- [HTTPHostnameModifier](#httphostnamemodifier)
+
+| Value | Description |
+| ----- | ----------- |
+| `Header` | HeaderHTTPHostnameModifier indicates that the Host header value would be replaced with the value of the header specified in header. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-header |
+| `Backend` | BackendHTTPHostnameModifier indicates that the Host header value would be replaced by the DNS name of the backend if it exists. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-auto-host-rewrite |
+
+
+#### HTTPPathModifier
+
+
+
+
+
+_Appears in:_
+- [HTTPURLRewriteFilter](#httpurlrewritefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[HTTPPathModifierType](#httppathmodifiertype)_ | true | |
+| `replaceRegexMatch` | _[ReplaceRegexMatch](#replaceregexmatch)_ | false | ReplaceRegexMatch defines a path regex rewrite. The path portions matched by the regex pattern are replaced by the defined substitution. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-regex-rewrite Some examples: (1) replaceRegexMatch: pattern: ^/service/([^/]+)(/.*)$ substitution: \2/instance/\1 Would transform /service/foo/v1/api into /v1/api/instance/foo. (2) replaceRegexMatch: pattern: one substitution: two Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/two/zzz. (3) replaceRegexMatch: pattern: ^(.*?)one(.*)$ substitution: \1two\2 Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/one/zzz. (3) replaceRegexMatch: pattern: (?i)/xxx/ substitution: /yyy/ Would transform path /aaa/XxX/bbb into /aaa/yyy/bbb (case-insensitive). |
+
+
+#### HTTPPathModifierType
+
+_Underlying type:_ _string_
+
+HTTPPathModifierType defines the type of path redirect or rewrite.
+
+_Appears in:_
+- [HTTPPathModifier](#httppathmodifier)
+
+| Value | Description |
+| ----- | ----------- |
+| `ReplaceRegexMatch` | RegexHTTPPathModifier This type of modifier indicates that the portions of the path that match the specified regex would be substituted with the specified substitution value https://www.envoyproxy.io/docs/envoy/latest/api-v3/type/matcher/v3/regex.proto#type-matcher-v3-regexmatchandsubstitute |
+
+
+#### HTTPRouteFilter
+
+
+
+HTTPRouteFilter is a custom Envoy Gateway HTTPRouteFilter which provides extended
+traffic processing options such as path regex rewrite, direct response and more.
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`HTTPRouteFilter`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[HTTPRouteFilterSpec](#httproutefilterspec)_ | true | Spec defines the desired state of HTTPRouteFilter. |
+
+
+#### HTTPRouteFilterSpec
+
+
+
+HTTPRouteFilterSpec defines the desired state of HTTPRouteFilter.
+
+_Appears in:_
+- [HTTPRouteFilter](#httproutefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `urlRewrite` | _[HTTPURLRewriteFilter](#httpurlrewritefilter)_ | false | |
+| `directResponse` | _[HTTPDirectResponseFilter](#httpdirectresponsefilter)_ | false | |
+
+
#### HTTPStatus
_Underlying type:_ _integer_
@@ -1870,6 +2046,22 @@ _Appears in:_
| --- | --- | --- | --- |
| `connectionIdleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. Default: 1 hour. |
| `maxConnectionDuration` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The maximum duration of an HTTP connection. Default: unlimited. |
+| `requestTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | RequestTimeout is the time until which entire response is received from the upstream. |
+
+
+#### HTTPURLRewriteFilter
+
+
+
+HTTPURLRewriteFilter define rewrites of HTTP URL components such as path and host
+
+_Appears in:_
+- [HTTPRouteFilterSpec](#httproutefilterspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `hostname` | _[HTTPHostnameModifier](#httphostnamemodifier)_ | false | Hostname is the value to be used to replace the Host header value during forwarding. |
+| `path` | _[HTTPPathModifier](#httppathmodifier)_ | false | Path defines a path rewrite. |
#### HTTPWasmCodeSource
@@ -1884,7 +2076,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | _string_ | true | URL is the URL containing the Wasm code. |
-| `sha256` | _string_ | false | SHA256 checksum that will be used to verify the Wasm code.
If not specified, Envoy Gateway will not verify the downloaded Wasm code. kubebuilder:validation:Pattern=`^[a-f0-9]{64}$` |
+| `sha256` | _string_ | false | SHA256 checksum that will be used to verify the Wasm code.
If not specified, Envoy Gateway will not verify the downloaded Wasm code. kubebuilder:validation:Pattern=`^[a-f0-9]\{64\}$` |
#### Header
@@ -1902,6 +2094,21 @@ _Appears in:_
| `name` | _string_ | true | Name of the header to hash. |
+#### HeaderMatch
+
+
+
+HeaderMatch defines the match attributes within the HTTP Headers of the request.
+
+_Appears in:_
+- [RateLimitSelectCondition](#ratelimitselectcondition)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[HeaderMatchType](#headermatchtype)_ | false | Type specifies how to match against the value of the header. |
+| `name` | _string_ | true | Name of the HTTP header. |
+| `value` | _string_ | false | Value within the HTTP header. Due to the case-insensitivity of header names, "foo" and "Foo" are considered equivalent. Do not set this field when Type="Distinct", implying matching on any/all unique values within the header. |
+| `invert` | _boolean_ | false | Invert specifies whether the value match result will be inverted. Do not set this field when Type="Distinct", implying matching on any/all unique values within the header. |
#### HeaderMatchType
@@ -1937,6 +2144,7 @@ _Appears in:_
| `xForwardedClientCert` | _[XForwardedClientCert](#xforwardedclientcert)_ | false | XForwardedClientCert configures how Envoy Proxy handle the x-forwarded-client-cert (XFCC) HTTP header.
x-forwarded-client-cert (XFCC) is an HTTP header used to forward the certificate information of part or all of the clients or proxies that a request has flowed through, on its way from the client to the server.
Envoy proxy may choose to sanitize/append/forward the XFCC header before proxying the request.
If not set, the default behavior is sanitizing the XFCC header. |
| `withUnderscoresAction` | _[WithUnderscoresAction](#withunderscoresaction)_ | false | WithUnderscoresAction configures the action to take when an HTTP header with underscores is encountered. The default action is to reject the request. |
| `preserveXRequestID` | _boolean_ | false | PreserveXRequestID configures Envoy to keep the X-Request-ID header if passed for a request that is edge (Edge request is the request from external clients to front Envoy) and not reset it, which is the current Envoy behaviour. It defaults to false. |
+| `earlyRequestHeaders` | _[HTTPHeaderFilter](#httpheaderfilter)_ | false | EarlyRequestHeaders defines settings for early request header modification, before envoy performs routing, tracing and built-in header manipulation. |
#### HealthCheck
@@ -1948,6 +2156,7 @@ are healthy and can be used for routing.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -1982,10 +2191,26 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `address` | _string_ | true | Address defines the IP address of the backend endpoint. |
+| `address` | _string_ | true | Address defines the IP address of the backend endpoint. Supports both IPv4 and IPv6 addresses. |
| `port` | _integer_ | true | Port defines the port of the backend endpoint. |
+#### IPFamily
+
+_Underlying type:_ _string_
+
+IPFamily defines the IP family to use for the Envoy proxy.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Value | Description |
+| ----- | ----------- |
+| `IPv4` | IPv4 defines the IPv4 family. |
+| `IPv6` | IPv6 defines the IPv6 family. |
+| `DualStack` | DualStack defines the dual-stack family. When set to DualStack, Envoy proxy will listen on both IPv4 and IPv6 addresses for incoming client traffic, enabling support for both IP protocol versions. |
+
+
#### ImagePullPolicy
_Underlying type:_ _string_
@@ -2013,7 +2238,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | _string_ | true | URL is the URL of the OCI image. URL can be in the format of `registry/image:tag` or `registry/image@sha256:digest`. |
-| `sha256` | _string_ | false | SHA256 checksum that will be used to verify the OCI image.
It must match the digest of the OCI image.
If not specified, Envoy Gateway will not verify the downloaded OCI image. kubebuilder:validation:Pattern=`^[a-f0-9]{64}$` |
+| `sha256` | _string_ | false | SHA256 checksum that will be used to verify the OCI image.
It must match the digest of the OCI image.
If not specified, Envoy Gateway will not verify the downloaded OCI image. kubebuilder:validation:Pattern=`^[a-f0-9]\{64\}$` |
| `pullSecretRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | false | PullSecretRef is a reference to the secret containing the credentials to pull the image. Only support Kubernetes Secret resource from the same namespace. |
@@ -2031,6 +2256,21 @@ _Appears in:_
| `Host` | InfrastructureProviderTypeHost defines the "Host" provider. |
+#### InvalidMessageAction
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [HTTP2Settings](#http2settings)
+
+| Value | Description |
+| ----- | ----------- |
+| `TerminateConnection` | |
+| `TerminateStream` | |
+
+
#### JSONPatchOperation
@@ -2040,11 +2280,13 @@ https://datatracker.ietf.org/doc/html/rfc6902
_Appears in:_
- [EnvoyJSONPatchConfig](#envoyjsonpatchconfig)
+- [ProxyBootstrap](#proxybootstrap)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `op` | _[JSONPatchOperationType](#jsonpatchoperationtype)_ | true | Op is the type of operation to perform |
-| `path` | _string_ | true | Path is the location of the target document/field where the operation will be performed Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
+| `path` | _string_ | false | Path is a JSONPointer expression. Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. It specifies the location of the target document/field where the operation will be performed |
+| `jsonPath` | _string_ | false | JSONPath is a JSONPath expression. Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details. It produces one or more JSONPointer expressions based on the given JSON document. If no JSONPointer is found, it will result in an error. If the 'Path' property is also set, it will be appended to the resulting JSONPointer expressions from the JSONPath evaluation. This is useful when creating a property that does not yet exist in the JSON document. The final JSONPointer expressions specifies the locations in the target document/field where the operation will be applied. |
| `from` | _string_ | false | From is the source location of the value to be copied or moved. Only valid for move or copy operations Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
| `value` | _[JSON](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#json-v1-apiextensions-k8s-io)_ | false | Value is the new value of the path location. The value is only used by the `add` and `replace` operations. |
@@ -2075,6 +2317,37 @@ _Appears in:_
| `providers` | _[JWTProvider](#jwtprovider) array_ | true | Providers defines the JSON Web Token (JWT) authentication provider type. When multiple JWT providers are specified, the JWT is considered valid if any of the providers successfully validate the JWT. For additional details, see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html. |
+#### JWTClaim
+
+
+
+JWTClaim specifies a claim in a JWT token.
+
+_Appears in:_
+- [JWTPrincipal](#jwtprincipal)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | true | Name is the name of the claim. If it is a nested claim, use a dot (.) separated string as the name to represent the full path to the claim. For example, if the claim is in the "department" field in the "organization" field, the name should be "organization.department". |
+| `valueType` | _[JWTClaimValueType](#jwtclaimvaluetype)_ | false | ValueType is the type of the claim value. Only String and StringArray types are supported for now. |
+| `values` | _string array_ | true | Values are the values that the claim must match. If the claim is a string type, the specified value must match exactly. If the claim is a string array type, the specified value must match one of the values in the array. If multiple values are specified, one of the values must match for the rule to match. |
+
+
+#### JWTClaimValueType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [JWTClaim](#jwtclaim)
+
+| Value | Description |
+| ----- | ----------- |
+| `String` | |
+| `StringArray` | |
+
+
#### JWTExtractor
@@ -2105,7 +2378,25 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | _string_ | true | Name is the HTTP header name to retrieve the token |
-| `valuePrefix` | _string_ | false | ValuePrefix is the prefix that should be stripped before extracting the token. The format would be used by Envoy like "{ValuePrefix}". For example, "Authorization: Bearer ", then the ValuePrefix="Bearer " with a space at the end. |
+| `valuePrefix` | _string_ | false | ValuePrefix is the prefix that should be stripped before extracting the token. The format would be used by Envoy like "\{ValuePrefix\}". For example, "Authorization: Bearer ", then the ValuePrefix="Bearer " with a space at the end. |
+
+
+#### JWTPrincipal
+
+
+
+JWTPrincipal specifies the client identity of a request based on the JWT claims and scopes.
+At least one of the claims or scopes must be specified.
+Claims and scopes are And-ed together if both are specified.
+
+_Appears in:_
+- [Principal](#principal)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `provider` | _string_ | true | Provider is the name of the JWT provider that used to verify the JWT token. In order to use JWT claims for authorization, you must configure the JWT authentication with the same provider in the same `SecurityPolicy`. |
+| `claims` | _[JWTClaim](#jwtclaim) array_ | false | Claims are the claims in a JWT token.
If multiple claims are specified, all claims must match for the rule to match. For example, if there are two claims: one for the audience and one for the issuer, the rule will match only if both the audience and the issuer match. |
+| `scopes` | _[JWTScope](#jwtscope) array_ | false | Scopes are a special type of claim in a JWT token that represents the permissions of the client.
The value of the scopes field should be a space delimited string that is expected in the scope parameter, as defined in RFC 6749: https://datatracker.ietf.org/doc/html/rfc6749#page-23.
If multiple scopes are specified, all scopes must match for the rule to match. |
#### JWTProvider
@@ -2128,6 +2419,17 @@ _Appears in:_
| `extractFrom` | _[JWTExtractor](#jwtextractor)_ | false | ExtractFrom defines different ways to extract the JWT token from HTTP request. If empty, it defaults to extract JWT token from the Authorization HTTP request header using Bearer schema or access_token from query parameters. |
+#### JWTScope
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [JWTPrincipal](#jwtprincipal)
+
+
+
#### KubernetesContainerSpec
@@ -2151,7 +2453,7 @@ _Appears in:_
-KubernetesDaemonsetSpec defines the desired state of the Kubernetes daemonset resource.
+KubernetesDaemonSetSpec defines the desired state of the Kubernetes daemonset resource.
_Appears in:_
- [EnvoyProxyKubernetesProvider](#envoyproxykubernetesprovider)
@@ -2222,7 +2524,9 @@ _Appears in:_
-KubernetesPatchSpec defines how to perform the patch operation
+KubernetesPatchSpec defines how to perform the patch operation.
+Note that `value` can be an in-line YAML document, as can be seen in e.g. (the example of patching the Envoy proxy Deployment)[https://gateway.envoyproxy.io/docs/tasks/operations/customize-envoyproxy/#patching-deployment-for-envoyproxy].
+Note also that, currently, strings containing literal JSON are _rejected_.
_Appears in:_
- [KubernetesDaemonSetSpec](#kubernetesdaemonsetspec)
@@ -2284,6 +2588,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `annotations` | _object (keys:string, values:string)_ | false | Annotations that should be appended to the service. By default, no annotations are appended. |
+| `labels` | _object (keys:string, values:string)_ | false | Labels that should be appended to the service. By default, no labels are appended. |
| `type` | _[ServiceType](#servicetype)_ | false | Type determines how the Service is exposed. Defaults to LoadBalancer. Valid options are ClusterIP, LoadBalancer and NodePort. "LoadBalancer" means a service will be exposed via an external load balancer (if the cloud provider supports it). "ClusterIP" means a service will only be accessible inside the cluster, via the cluster IP. "NodePort" means a service will be exposed on a static Port on all Nodes of the cluster. |
| `loadBalancerClass` | _string_ | false | LoadBalancerClass, when specified, allows for choosing the LoadBalancer provider implementation if more than one are available or is otherwise expected to be specified |
| `allocateLoadBalancerNodePorts` | _boolean_ | false | AllocateLoadBalancerNodePorts defines if NodePorts will be automatically allocated for services with type LoadBalancer. Default is "true". It may be set to "false" if the cluster load-balancer does not rely on NodePorts. If the caller requests specific NodePorts (by specifying a value), those requests will be respected, regardless of this field. This field may only be set for services with type LoadBalancer and will be cleared if the type is changed to any other type. |
@@ -2360,6 +2665,7 @@ LoadBalancer defines the load balancer policy to be applied.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -2417,6 +2723,19 @@ _Appears in:_
| `error` | LogLevelError defines the "Error" logging level. |
+#### MergeType
+
+_Underlying type:_ _string_
+
+MergeType defines the type of merge operation
+
+_Appears in:_
+- [KubernetesPatchSpec](#kubernetespatchspec)
+
+| Value | Description |
+| ----- | ----------- |
+| `StrategicMerge` | StrategicMerge indicates a strategic merge patch type |
+| `JSONMerge` | JSONMerge indicates a JSON merge patch type |
#### MetricSinkType
@@ -2449,6 +2768,7 @@ _Appears in:_
| `clientID` | _string_ | true | The client ID to be used in the OIDC [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). |
| `clientSecret` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the OIDC client secret to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
This is an Opaque secret. The client secret should be stored in the key "client-secret". |
| `cookieNames` | _[OIDCCookieNames](#oidccookienames)_ | false | The optional cookie name overrides to be used for Bearer and IdToken cookies in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, uses a randomly generated suffix |
+| `cookieDomain` | _string_ | false | The optional domain to set the access and ID token cookies on. If not set, the cookies will default to the host of the request, not including the subdomains. If set, the cookies will be set on the specified domain and all subdomains. This means that requests to any subdomain will not require reauthentication after users log in to the parent domain. |
| `scopes` | _string array_ | false | The OIDC scopes to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). The "openid" scope is always added to the list of scopes if not already specified. |
| `resources` | _string array_ | false | The OIDC resources to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). |
| `redirectURL` | _string_ | true | The redirect URL to be used in the OIDC [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" |
@@ -2485,6 +2805,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `issuer` | _string_ | true | The OIDC Provider's [issuer identifier](https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery). Issuer MUST be a URI RFC 3986 [RFC3986] with a scheme component that MUST be https, a host component, and optionally, port and path components and no query or fragment components. |
| `authorizationEndpoint` | _string_ | false | The OIDC Provider's [authorization endpoint](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint). If not provided, EG will try to discover it from the provider's [Well-Known Configuration Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). |
| `tokenEndpoint` | _string_ | false | The OIDC Provider's [token endpoint](https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint). If not provided, EG will try to discover it from the provider's [Well-Known Configuration Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). |
@@ -2501,9 +2824,11 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `host` | _string_ | false | Host define the extension service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the extension service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the access log will be sent. Only Service kind is supported for now. |
| `resources` | _object (keys:string, values:string)_ | false | Resources is a set of labels that describe the source of a log entry, including envoy node info. It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). |
@@ -2623,17 +2948,15 @@ _Appears in:_
-Principal specifies the client identity of a request.
-A client identity can be a client IP, a JWT claim, username from the Authorization header,
-or any other identity that can be extracted from a custom header.
-Currently, only the client IP is supported.
+If there are multiple principal types, all principals must match for the rule to match.
_Appears in:_
- [AuthorizationRule](#authorizationrule)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `clientCIDRs` | _[CIDR](#cidr) array_ | true | ClientCIDRs are the IP CIDR ranges of the client. Valid examples are "192.168.1.0/24" or "2001:db8::/64"
The client IP is inferred from the X-Forwarded-For header, a custom header, or the proxy protocol. You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in the `ClientTrafficPolicy` to configure how the client IP is detected. |
+| `clientCIDRs` | _[CIDR](#cidr) array_ | false | ClientCIDRs are the IP CIDR ranges of the client. Valid examples are "192.168.1.0/24" or "2001:db8::/64"
If multiple CIDR ranges are specified, one of the CIDR ranges must match the client IP for the rule to match.
The client IP is inferred from the X-Forwarded-For header, a custom header, or the proxy protocol. You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in the `ClientTrafficPolicy` to configure how the client IP is detected. |
+| `jwt` | _[JWTPrincipal](#jwtprincipal)_ | false | JWT authorize the request based on the JWT claims and scopes. Note: in order to use JWT claims for authorization, you must configure the JWT authentication in the same `SecurityPolicy`. |
#### ProcessingModeOptions
@@ -2663,7 +2986,7 @@ _Appears in:_
| Value | Description |
| ----- | ----------- |
| `Kubernetes` | ProviderTypeKubernetes defines the "Kubernetes" provider. |
-| `File` | ProviderTypeFile defines the "File" provider. This type is not implemented until https://github.com/envoyproxy/gateway/issues/1001 is fixed. |
+| `Custom` | ProviderTypeCustom defines the "Custom" provider. |
#### ProxyAccessLog
@@ -2725,7 +3048,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `format` | _[ProxyAccessLogFormat](#proxyaccesslogformat)_ | false | Format defines the format of accesslog. This will be ignored if sink type is ALS. |
+| `matches` | _string array_ | true | Matches defines the match conditions for accesslog in CEL expression. An accesslog will be emitted only when one or more match conditions are evaluated to true. Invalid [CEL](https://www.envoyproxy.io/docs/envoy/latest/xds/type/v3/cel.proto.html#common-expression-language-cel-proto) expressions will be ignored. |
| `sinks` | _[ProxyAccessLogSink](#proxyaccesslogsink) array_ | true | Sinks defines the sinks of accesslog. |
+| `type` | _[ProxyAccessLogType](#proxyaccesslogtype)_ | false | Type defines the component emitting the accesslog, such as Listener and Route. If type not defined, the setting would apply to: (1) All Routes. (2) Listeners if and only if Envoy does not find a matching route for a request. If type is defined, the accesslog settings would apply to the relevant component (as-is). |
#### ProxyAccessLogSink
@@ -2761,6 +3086,21 @@ _Appears in:_
| `OpenTelemetry` | ProxyAccessLogSinkTypeOpenTelemetry defines the OpenTelemetry accesslog sink. When the provider is Kubernetes, EnvoyGateway always sends `k8s.namespace.name` and `k8s.pod.name` as additional attributes. |
+#### ProxyAccessLogType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [ProxyAccessLogSetting](#proxyaccesslogsetting)
+
+| Value | Description |
+| ----- | ----------- |
+| `Listener` | ProxyAccessLogTypeListener defines the accesslog for Listeners. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-access-log |
+| `Route` | ProxyAccessLogTypeRoute defines the accesslog for HTTP, GRPC, UDP and TCP Routes. https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/udp/udp_proxy/v3/udp_proxy.proto#envoy-v3-api-field-extensions-filters-udp-udp-proxy-v3-udpproxyconfig-access-log https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto#envoy-v3-api-field-extensions-filters-network-tcp-proxy-v3-tcpproxy-access-log https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-access-log |
+
+
#### ProxyBootstrap
@@ -2772,8 +3112,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `type` | _[BootstrapType](#bootstraptype)_ | false | Type is the type of the bootstrap configuration, it should be either Replace or Merge. If unspecified, it defaults to Replace. |
-| `value` | _string_ | true | Value is a YAML string of the bootstrap. |
+| `type` | _[BootstrapType](#bootstraptype)_ | false | Type is the type of the bootstrap configuration, it should be either Replace, Merge, or JSONPatch. If unspecified, it defaults to Replace. |
+| `value` | _string_ | false | Value is a YAML string of the bootstrap. |
+| `jsonPatches` | _[JSONPatchOperation](#jsonpatchoperation) array_ | true | JSONPatches is an array of JSONPatches to be applied to the default bootstrap. Patches are applied in the order in which they are defined. |
#### ProxyLogComponent
@@ -2843,8 +3184,9 @@ _Appears in:_
| `prometheus` | _[ProxyPrometheusProvider](#proxyprometheusprovider)_ | true | Prometheus defines the configuration for Admin endpoint `/stats/prometheus`. |
| `sinks` | _[ProxyMetricSink](#proxymetricsink) array_ | true | Sinks defines the metric sinks where metrics are sent to. |
| `matches` | _[StringMatch](#stringmatch) array_ | true | Matches defines configuration for selecting specific metrics instead of generating all metrics stats that are enabled by default. This helps reduce CPU and memory overhead in Envoy, but eliminating some stats may after critical functionality. Here are the stats that we strongly recommend not disabling: `cluster_manager.warming_clusters`, `cluster..membership_total`,`cluster..membership_healthy`, `cluster..membership_degraded`,reference https://github.com/envoyproxy/envoy/issues/9856, https://github.com/envoyproxy/envoy/issues/14610 |
-| `enableVirtualHostStats` | _boolean_ | true | EnableVirtualHostStats enables envoy stat metrics for virtual hosts. |
-| `enablePerEndpointStats` | _boolean_ | true | EnablePerEndpointStats enables per endpoint envoy stats metrics. Please use with caution. |
+| `enableVirtualHostStats` | _boolean_ | false | EnableVirtualHostStats enables envoy stat metrics for virtual hosts. |
+| `enablePerEndpointStats` | _boolean_ | false | EnablePerEndpointStats enables per endpoint envoy stats metrics. Please use with caution. |
+| `enableRequestResponseSizesStats` | _boolean_ | false | EnableRequestResponseSizesStats enables publishing of histograms tracking header and body sizes of requests and responses. |
#### ProxyOpenTelemetrySink
@@ -2858,9 +3200,11 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `host` | _string_ | false | Host define the service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the metric will be sent. Only Service kind is supported for now. |
#### ProxyPrometheusProvider
@@ -2887,6 +3231,7 @@ when communicating with the backend.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -3128,6 +3473,15 @@ _Appears in:_
| `url` | _string_ | true | URL is the endpoint of the trace collector that supports the OTLP protocol |
+#### RateLimitTracingProviderType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [RateLimitTracingProvider](#ratelimittracingprovider)
+
#### RateLimitType
@@ -3207,6 +3561,21 @@ _Appears in:_
| `uri` | _string_ | true | URI is the HTTPS URI to fetch the JWKS. Envoy's system trust bundle is used to validate the server certificate. |
+#### ReplaceRegexMatch
+
+
+
+
+
+_Appears in:_
+- [HTTPPathModifier](#httppathmodifier)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `pattern` | _string_ | true | Pattern matches a regular expression against the value of the HTTP Path.The regex string must adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax. |
+| `substitution` | _string_ | true | Substitution is an expression that replaces the matched portion.The expression may include numbered capture groups that adhere to syntax documented in https://github.com/google/re2/wiki/Syntax. |
+
+
#### RequestHeaderCustomTag
@@ -3236,6 +3605,36 @@ _Appears in:_
| `File` | ResourceProviderTypeFile defines the "File" provider. |
+#### ResponseOverride
+
+
+
+ResponseOverride defines the configuration to override specific responses with a custom one.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `match` | _[CustomResponseMatch](#customresponsematch)_ | true | Match configuration. |
+| `response` | _[CustomResponse](#customresponse)_ | true | Response configuration. |
+
+
+#### ResponseValueType
+
+_Underlying type:_ _string_
+
+ResponseValueType defines the types of values for the response body supported by Envoy Gateway.
+
+_Appears in:_
+- [CustomResponseBody](#customresponsebody)
+
+| Value | Description |
+| ----- | ----------- |
+| `Inline` | ResponseValueTypeInline defines the "Inline" response body type. |
+| `ValueRef` | ResponseValueTypeValueRef defines the "ValueRef" response body type. |
+
+
#### Retry
@@ -3244,6 +3643,7 @@ Retry defines the retry strategy to be applied.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -3289,8 +3689,7 @@ _Appears in:_
SecurityPolicy allows the user to configure various security settings for a
Gateway.
-_Appears in:_
-- [SecurityPolicyList](#securitypolicylist)
+
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -3301,22 +3700,6 @@ _Appears in:_
| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of SecurityPolicy. |
-#### SecurityPolicyList
-
-
-
-SecurityPolicyList contains a list of SecurityPolicy resources.
-
-
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`SecurityPolicyList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[SecurityPolicy](#securitypolicy) array_ | true | |
-
-
#### SecurityPolicySpec
@@ -3372,6 +3755,35 @@ _Appears in:_
| `NodePort` | ServiceTypeNodePort means a service will be exposed on each Kubernetes Node at a static Port, common across all Nodes. |
+#### Session
+
+
+
+Session defines settings related to TLS session management.
+
+_Appears in:_
+- [ClientTLSSettings](#clienttlssettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `resumption` | _[SessionResumption](#sessionresumption)_ | false | Resumption determines the proxy's supported TLS session resumption option. By default, Envoy Gateway does not enable session resumption. Use sessionResumption to enable stateful and stateless session resumption. Users should consider security impacts of different resumption methods. Performance gains from resumption are diminished when Envoy proxy is deployed with more than one replica. |
+
+
+#### SessionResumption
+
+
+
+SessionResumption defines supported tls session resumption methods and their associated configuration.
+
+_Appears in:_
+- [Session](#session)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `stateless` | _[StatelessTLSSessionResumption](#statelesstlssessionresumption)_ | false | Stateless defines setting for stateless (session-ticket based) session resumption |
+| `stateful` | _[StatefulTLSSessionResumption](#statefultlssessionresumption)_ | false | Stateful defines setting for stateful (session-id based) session resumption |
+
+
#### ShutdownConfig
@@ -3383,8 +3795,8 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `drainTimeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds. If unspecified, defaults to 600 seconds. |
-| `minDrainDuration` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete. If unspecified, defaults to 5 seconds. |
+| `drainTimeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds. If unspecified, defaults to 60 seconds. |
+| `minDrainDuration` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete. If unspecified, defaults to 10 seconds. |
#### ShutdownManager
@@ -3415,6 +3827,19 @@ _Appears in:_
| `window` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | Window defines the duration of the warm up period for newly added host. During slow start window, traffic sent to the newly added hosts will gradually increase. Currently only supports linear growth of traffic. For additional details, see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig |
+#### SourceMatch
+
+
+
+
+
+_Appears in:_
+- [RateLimitSelectCondition](#ratelimitselectcondition)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[SourceMatchType](#sourcematchtype)_ | false | |
+| `value` | _string_ | true | Value is the IP CIDR that represents the range of Source IP Addresses of the client. These could also be the intermediate addresses through which the request has flown through and is part of the `X-Forwarded-For` header. For example, `192.168.0.1/32`, `192.168.0.0/24`, `001:db8::/64`. |
#### SourceMatchType
@@ -3432,6 +3857,83 @@ _Appears in:_
| `Distinct` | SourceMatchDistinct Each IP Address within the specified Source IP CIDR is treated as a distinct client selector and uses a separate rate limit bucket/counter. Note: This is only supported for Global Rate Limits. |
+#### StatefulTLSSessionResumption
+
+
+
+StatefulTLSSessionResumption defines the stateful (session-id based) type of TLS session resumption.
+Note: When Envoy Proxy is deployed with more than one replica, session caches are not synchronized
+between instances, possibly leading to resumption failures.
+Envoy does not re-validate client certificates upon session resumption.
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-routematch-tlscontextmatchoptions
+
+_Appears in:_
+- [SessionResumption](#sessionresumption)
+
+
+
+#### StatelessTLSSessionResumption
+
+
+
+StatelessTLSSessionResumption defines the stateless (session-ticket based) type of TLS session resumption.
+Note: When Envoy Proxy is deployed with more than one replica, session ticket encryption keys are not
+synchronized between instances, possibly leading to resumption failures.
+In-memory session ticket encryption keys are rotated every 48 hours.
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#extensions-transport-sockets-tls-v3-tlssessionticketkeys
+https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#Session-tickets
+
+_Appears in:_
+- [SessionResumption](#sessionresumption)
+
+
+
+#### StatusCodeMatch
+
+
+
+StatusCodeMatch defines the configuration for matching a status code.
+
+_Appears in:_
+- [CustomResponseMatch](#customresponsematch)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[StatusCodeValueType](#statuscodevaluetype)_ | true | Type is the type of value. Valid values are Value and Range, default is Value. |
+| `value` | _integer_ | false | Value contains the value of the status code. |
+| `range` | _[StatusCodeRange](#statuscoderange)_ | false | Range contains the range of status codes. |
+
+
+#### StatusCodeRange
+
+
+
+StatusCodeRange defines the configuration for define a range of status codes.
+
+_Appears in:_
+- [StatusCodeMatch](#statuscodematch)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `start` | _integer_ | true | Start of the range, including the start value. |
+| `end` | _integer_ | true | End of the range, including the end value. |
+
+
+#### StatusCodeValueType
+
+_Underlying type:_ _string_
+
+StatusCodeValueType defines the types of values for the status code match supported by Envoy Gateway.
+
+_Appears in:_
+- [StatusCodeMatch](#statuscodematch)
+
+| Value | Description |
+| ----- | ----------- |
+| `Value` | StatusCodeValueTypeValue defines the "Value" status code match type. |
+| `Range` | StatusCodeValueTypeRange defines the "Range" status code match type. |
+
+
#### StringMatch
@@ -3505,6 +4007,7 @@ TCPKeepalive define the TCP Keepalive configuration.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -3595,6 +4098,7 @@ Timeout defines configuration for timeouts related to connections.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -3613,10 +4117,12 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `type` | _[TracingProviderType](#tracingprovidertype)_ | true | Type defines the tracing provider type. |
| `host` | _string_ | false | Host define the provider service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the provider service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the trace will be sent. Only Service kind is supported for now. |
| `zipkin` | _[ZipkinTracingProvider](#zipkintracingprovider)_ | false | Zipkin defines the Zipkin tracing provider configuration |
@@ -3634,6 +4140,7 @@ _Appears in:_
| `OpenTelemetry` | |
| `OpenTelemetry` | |
| `Zipkin` | |
+| `Datadog` | |
#### TriggerEnum
@@ -3837,13 +4344,15 @@ _Appears in:_
XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address.
+Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
+for more details.
_Appears in:_
- [ClientIPDetectionSettings](#clientipdetectionsettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `numTrustedHops` | _integer_ | false | NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP headers to trust when determining the origin client's IP address. Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for for more details. |
+| `numTrustedHops` | _integer_ | false | NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP headers to trust when determining the origin client's IP address. Only one of NumTrustedHops and TrustedCIDRs must be set. |
#### ZipkinTracingProvider
diff --git a/site/content/en/docs/boilerplates/prerequisites.md b/site/content/en/docs/boilerplates/prerequisites.md
new file mode 100644
index 00000000000..064238e4d13
--- /dev/null
+++ b/site/content/en/docs/boilerplates/prerequisites.md
@@ -0,0 +1,24 @@
+---
+---
+
+Follow the steps from the [Quickstart](../tasks/quickstart) task to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+Verify the Gateway status:
+
+{{< tabpane text=true >}}
+{{% tab header="kubectl" %}}
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+{{% /tab %}}
+{{% tab header="egctl (experimental)" %}}
+
+```shell
+egctl x status gateway -v
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
diff --git a/site/content/en/docs/boilerplates/rollout-envoy-gateway.md b/site/content/en/docs/boilerplates/rollout-envoy-gateway.md
new file mode 100644
index 00000000000..9072526868c
--- /dev/null
+++ b/site/content/en/docs/boilerplates/rollout-envoy-gateway.md
@@ -0,0 +1,10 @@
+---
+---
+
+> After updating the `ConfigMap`, you will need to wait the configuration kicks in.
+> You can **force** the configuration to be reloaded by restarting the `envoy-gateway` deployment.
+>
+> ```shell
+> kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
+> ```
+>
\ No newline at end of file
diff --git a/site/content/en/docs/concepts/concepts_overview.md b/site/content/en/docs/concepts/concepts_overview.md
index 31838b520f2..6f37f87f283 100644
--- a/site/content/en/docs/concepts/concepts_overview.md
+++ b/site/content/en/docs/concepts/concepts_overview.md
@@ -10,13 +10,12 @@ There are several resources that play a part in enabling you to meet your Kubern
There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
-# Overview
-
-## Kubernetes Gateway API Resources
+### Kubernetes Gateway API Resources
- **GatewayClass:** Defines a class of Gateways with common configuration.
- **Gateway:** Specifies how traffic can enter the cluster.
- **Routes:** **HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute:** Define routing rules for different types of traffic.
-## Envoy Gateway (EG) API Resources
+
+### Envoy Gateway (EG) API Resources
- **EnvoyProxy:** Represents the deployment and configuration of the Envoy proxy within a Kubernetes cluster, managing its lifecycle and settings.
- **EnvoyPatchPolicy, ClientTrafficPolicy, SecurityPolicy, BackendTrafficPolicy, EnvoyExtensionPolicy, BackendTLSPolicy:** Additional policies and configurations specific to Envoy Gateway.
- **Backend:** A resource that makes routing to cluster-external backends easier and makes access to external processes via Unix Domain Sockets possible.
@@ -28,12 +27,14 @@ There are several resources that play a part in enabling you to meet your Kubern
| [HTTPRoute][3] [GRPCRoute][4] [TLSRoute][5] [TCPRoute][6] [UDPRoute][7] | Gateway API | Yes | Routing | Gateway | Define routing rules for different types of traffic. **Note:**_For simplicity these resources are referenced collectively as Route in the References column_ |
| [Backend][8] | EG API | No | Routing | N/A | Used for routing to cluster-external backends using FQDN or IP. Can also be used when you want to extend Envoy with external processes accessed via Unix Domain Sockets. |
| [ClientTrafficPolicy][9] | EG API | No | Traffic Handling | Gateway | Specifies policies for handling client traffic, including rate limiting, retries, and other client-specific configurations. |
-| [BackendTrafficPolicy][10] | EG API | No | Traffic Handling | Gateway Route | Specifies policies for traffic directed towards backend services, including load balancing, health checks, and failover strategies. **Note:**_Most specific configuration wins_ |
-| [SecurityPolicy][11] | EG API | No | Security | Gateway Route | Defines security-related policies such as authentication, authorization, and encryption settings for traffic handled by Envoy Gateway. **Note:**_Most specific configuration wins_ |
+| [BackendTrafficPolicy][10] | EG API | No | Traffic Handling | Gateway, Route | Specifies policies for traffic directed towards backend services, including load balancing, health checks, and failover strategies. **Note:**_Most specific configuration wins_ |
+| [SecurityPolicy][11] | EG API | No | Security | Gateway, Route | Defines security-related policies such as authentication, authorization, and encryption settings for traffic handled by Envoy Gateway. **Note:**_Most specific configuration wins_ |
| [BackendTLSPolicy][12] | Gateway API | No | Security | Service | Defines TLS settings for backend connections, including certificate management, TLS version settings, and other security configurations. This policy is applied to Kubernetes Services. |
-| [EnvoyProxy][13] | EG API | No | Customize & Extend | GatewayClass Gateway | The EnvoyProxy resource represents the deployment and configuration of the Envoy proxy itself within a Kubernetes cluster, managing its lifecycle and settings. **Note:**_Most specific configuration wins_ |
-| [EnvoyPatchPolicy][14] | EG API | No | Customize & Extend | GatewayClass Gateway | This policy defines custom patches to be applied to Envoy Gateway resources, allowing users to tailor the configuration to their specific needs. **Note:**_Most specific configuration wins_ |
-| [EnvoyExtensionPolicy][15] | EG API | No | Customize & Extend | Gateway Route, Backend | Allows for the configuration of Envoy proxy extensions, enabling custom behavior and functionality. **Note:**_Most specific configuration wins_ |
+| [EnvoyProxy][13] | EG API | No | Customize & Extend | GatewayClass, Gateway | The EnvoyProxy resource represents the deployment and configuration of the Envoy proxy itself within a Kubernetes cluster, managing its lifecycle and settings. **Note:**_Most specific configuration wins_ |
+| [EnvoyPatchPolicy][14] | EG API | No | Customize & Extend | GatewayClass, Gateway | This policy defines custom patches to be applied to Envoy Gateway resources, allowing users to tailor the configuration to their specific needs. **Note:**_Most specific configuration wins_ |
+| [EnvoyExtensionPolicy][15] | EG API | No | Customize & Extend | Gateway, Route, Backend| Allows for the configuration of Envoy proxy extensions, enabling custom behavior and functionality. **Note:**_Most specific configuration wins_ |
+| [HTTPRouteFilter][16] | EG API | No | Customize & Extend | HTTPRoute | Allows for the additional request/response processing. |
+
@@ -51,4 +52,5 @@ There are several resources that play a part in enabling you to meet your Kubern
[12]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
[13]: ../api/extension_types#envoyproxy
[14]: ../api/extension_types#envoypatchpolicy
-[15]: ../api/extension_types#envoyextensionpolicy
\ No newline at end of file
+[15]: ../api/extension_types#envoyextensionpolicy
+[16]: ../api/extension_types#httproutefilter
diff --git a/site/content/en/docs/install/gateway-addons-helm-api.md b/site/content/en/docs/install/gateway-addons-helm-api.md
index 448aa91e504..dce51039fa2 100644
--- a/site/content/en/docs/install/gateway-addons-helm-api.md
+++ b/site/content/en/docs/install/gateway-addons-helm-api.md
@@ -24,16 +24,20 @@ An Add-ons Helm chart for Envoy Gateway
| Repository | Name | Version |
|------------|------|---------|
| https://fluent.github.io/helm-charts | fluent-bit | 0.30.4 |
+| https://grafana.github.io/helm-charts | alloy | 0.9.2 |
| https://grafana.github.io/helm-charts | grafana | 8.0.0 |
| https://grafana.github.io/helm-charts | loki | 4.8.0 |
| https://grafana.github.io/helm-charts | tempo | 1.3.1 |
-| https://open-telemetry.github.io/opentelemetry-helm-charts | opentelemetry-collector | 0.73.1 |
+| https://open-telemetry.github.io/opentelemetry-helm-charts | opentelemetry-collector | 0.108.0 |
| https://prometheus-community.github.io/helm-charts | prometheus | 25.21.0 |
## Values
| Key | Type | Default | Description |
|-----|------|---------|-------------|
+| alloy.alloy.configMap.content | string | `"// Write your Alloy config here:\nlogging {\n level = \"info\"\n format = \"logfmt\"\n}\nloki.write \"alloy\" {\n endpoint {\n url = \"http://loki.monitoring.svc:3100/loki/api/v1/push\"\n }\n}\n// discovery.kubernetes allows you to find scrape targets from Kubernetes resources.\n// It watches cluster state and ensures targets are continually synced with what is currently running in your cluster.\ndiscovery.kubernetes \"pod\" {\n role = \"pod\"\n}\n\n// discovery.relabel rewrites the label set of the input targets by applying one or more relabeling rules.\n// If no rules are defined, then the input targets are exported as-is.\ndiscovery.relabel \"pod_logs\" {\n targets = discovery.kubernetes.pod.targets\n\n // Label creation - \"namespace\" field from \"__meta_kubernetes_namespace\"\n rule {\n source_labels = [\"__meta_kubernetes_namespace\"]\n action = \"replace\"\n target_label = \"namespace\"\n }\n\n // Label creation - \"pod\" field from \"__meta_kubernetes_pod_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_name\"]\n action = \"replace\"\n target_label = \"pod\"\n }\n\n // Label creation - \"container\" field from \"__meta_kubernetes_pod_container_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"container\"\n }\n\n // Label creation - \"app\" field from \"__meta_kubernetes_pod_label_app_kubernetes_io_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_label_app_kubernetes_io_name\"]\n action = \"replace\"\n target_label = \"app\"\n }\n\n // Label creation - \"job\" field from \"__meta_kubernetes_namespace\" and \"__meta_kubernetes_pod_container_name\"\n // Concatenate values __meta_kubernetes_namespace/__meta_kubernetes_pod_container_name\n rule {\n source_labels = [\"__meta_kubernetes_namespace\", \"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"job\"\n separator = \"/\"\n replacement = \"$1\"\n }\n\n // Label creation - \"container\" field from \"__meta_kubernetes_pod_uid\" and \"__meta_kubernetes_pod_container_name\"\n // Concatenate values __meta_kubernetes_pod_uid/__meta_kubernetes_pod_container_name.log\n rule {\n source_labels = [\"__meta_kubernetes_pod_uid\", \"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"__path__\"\n separator = \"/\"\n replacement = \"/var/log/pods/*$1/*.log\"\n }\n\n // Label creation - \"container_runtime\" field from \"__meta_kubernetes_pod_container_id\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_container_id\"]\n action = \"replace\"\n target_label = \"container_runtime\"\n regex = \"^(\\\\S+):\\\\/\\\\/.+$\"\n replacement = \"$1\"\n }\n}\n\n// loki.source.kubernetes tails logs from Kubernetes containers using the Kubernetes API.\nloki.source.kubernetes \"pod_logs\" {\n targets = discovery.relabel.pod_logs.output\n forward_to = [loki.process.pod_logs.receiver]\n}\n// loki.process receives log entries from other Loki components, applies one or more processing stages,\n// and forwards the results to the list of receivers in the component’s arguments.\nloki.process \"pod_logs\" {\n stage.static_labels {\n values = {\n cluster = \"envoy-gateway\",\n }\n }\n\n forward_to = [loki.write.alloy.receiver]\n}"` | |
+| alloy.enabled | bool | `false` | |
+| alloy.fullnameOverride | string | `"alloy"` | |
| fluent-bit.config.filters | string | `"[FILTER]\n Name kubernetes\n Match kube.*\n Merge_Log On\n Keep_Log Off\n K8S-Logging.Parser On\n K8S-Logging.Exclude On\n\n[FILTER]\n Name grep\n Match kube.*\n Regex $kubernetes['container_name'] ^envoy$\n\n[FILTER]\n Name parser\n Match kube.*\n Key_Name log\n Parser envoy\n Reserve_Data True\n"` | |
| fluent-bit.config.inputs | string | `"[INPUT]\n Name tail\n Path /var/log/containers/*.log\n multiline.parser docker, cri\n Tag kube.*\n Mem_Buf_Limit 5MB\n Skip_Long_Lines On\n"` | |
| fluent-bit.config.outputs | string | `"[OUTPUT]\n Name loki\n Match kube.*\n Host loki.monitoring.svc.cluster.local\n Port 3100\n Labels job=fluentbit, app=$kubernetes['labels']['app'], k8s_namespace_name=$kubernetes['namespace_name'], k8s_pod_name=$kubernetes['pod_name'], k8s_container_name=$kubernetes['container_name']\n"` | |
@@ -63,6 +67,7 @@ An Add-ons Helm chart for Envoy Gateway
| grafana.enabled | bool | `true` | |
| grafana.fullnameOverride | string | `"grafana"` | |
| grafana.service.type | string | `"LoadBalancer"` | |
+| grafana.testFramework.enabled | bool | `false` | |
| loki.backend.replicas | int | `0` | |
| loki.deploymentMode | string | `"SingleBinary"` | |
| loki.enabled | bool | `true` | |
@@ -81,29 +86,40 @@ An Add-ons Helm chart for Envoy Gateway
| loki.singleBinary.replicas | int | `1` | |
| loki.test.enabled | bool | `false` | |
| loki.write.replicas | int | `0` | |
-| opentelemetry-collector.config.exporters.logging.verbosity | string | `"detailed"` | |
+| opentelemetry-collector.config.exporters.debug.verbosity | string | `"detailed"` | |
| opentelemetry-collector.config.exporters.loki.endpoint | string | `"http://loki.monitoring.svc:3100/loki/api/v1/push"` | |
| opentelemetry-collector.config.exporters.otlp.endpoint | string | `"tempo.monitoring.svc:4317"` | |
| opentelemetry-collector.config.exporters.otlp.tls.insecure | bool | `true` | |
-| opentelemetry-collector.config.exporters.prometheus.endpoint | string | `"0.0.0.0:19001"` | |
-| opentelemetry-collector.config.extensions.health_check | object | `{}` | |
+| opentelemetry-collector.config.exporters.prometheus.endpoint | string | `"[${env:MY_POD_IP}]:19001"` | |
+| opentelemetry-collector.config.extensions.health_check.endpoint | string | `"[${env:MY_POD_IP}]:13133"` | |
| opentelemetry-collector.config.processors.attributes.actions[0].action | string | `"insert"` | |
| opentelemetry-collector.config.processors.attributes.actions[0].key | string | `"loki.attribute.labels"` | |
| opentelemetry-collector.config.processors.attributes.actions[0].value | string | `"k8s.pod.name, k8s.namespace.name"` | |
-| opentelemetry-collector.config.receivers.otlp.protocols.grpc.endpoint | string | `"${env:MY_POD_IP}:4317"` | |
-| opentelemetry-collector.config.receivers.otlp.protocols.http.endpoint | string | `"${env:MY_POD_IP}:4318"` | |
-| opentelemetry-collector.config.receivers.zipkin.endpoint | string | `"${env:MY_POD_IP}:9411"` | |
+| opentelemetry-collector.config.receivers.datadog.endpoint | string | `"[${env:MY_POD_IP}]:8126"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.grpc.endpoint | string | `"[${env:MY_POD_IP}]:14250"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.thrift_compact.endpoint | string | `"[${env:MY_POD_IP}]:6831"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.thrift_http.endpoint | string | `"[${env:MY_POD_IP}]:14268"` | |
+| opentelemetry-collector.config.receivers.otlp.protocols.grpc.endpoint | string | `"[${env:MY_POD_IP}]:4317"` | |
+| opentelemetry-collector.config.receivers.otlp.protocols.http.endpoint | string | `"[${env:MY_POD_IP}]:4318"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].job_name | string | `"opentelemetry-collector"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].scrape_interval | string | `"10s"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].static_configs[0].targets[0] | string | `"[${env:MY_POD_IP}]:8888"` | |
+| opentelemetry-collector.config.receivers.zipkin.endpoint | string | `"[${env:MY_POD_IP}]:9411"` | |
| opentelemetry-collector.config.service.extensions[0] | string | `"health_check"` | |
| opentelemetry-collector.config.service.pipelines.logs.exporters[0] | string | `"loki"` | |
| opentelemetry-collector.config.service.pipelines.logs.processors[0] | string | `"attributes"` | |
| opentelemetry-collector.config.service.pipelines.logs.receivers[0] | string | `"otlp"` | |
| opentelemetry-collector.config.service.pipelines.metrics.exporters[0] | string | `"prometheus"` | |
-| opentelemetry-collector.config.service.pipelines.metrics.receivers[0] | string | `"otlp"` | |
+| opentelemetry-collector.config.service.pipelines.metrics.receivers[0] | string | `"datadog"` | |
+| opentelemetry-collector.config.service.pipelines.metrics.receivers[1] | string | `"otlp"` | |
| opentelemetry-collector.config.service.pipelines.traces.exporters[0] | string | `"otlp"` | |
-| opentelemetry-collector.config.service.pipelines.traces.receivers[0] | string | `"otlp"` | |
-| opentelemetry-collector.config.service.pipelines.traces.receivers[1] | string | `"zipkin"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[0] | string | `"datadog"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[1] | string | `"otlp"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[2] | string | `"zipkin"` | |
+| opentelemetry-collector.config.service.telemetry.metrics.address | string | `"[${env:MY_POD_IP}]:8888"` | |
| opentelemetry-collector.enabled | bool | `false` | |
| opentelemetry-collector.fullnameOverride | string | `"otel-collector"` | |
+| opentelemetry-collector.image.repository | string | `"otel/opentelemetry-collector-contrib"` | |
| opentelemetry-collector.mode | string | `"deployment"` | |
| prometheus.alertmanager.enabled | bool | `false` | |
| prometheus.enabled | bool | `true` | |
diff --git a/site/content/en/docs/install/gateway-helm-api.md b/site/content/en/docs/install/gateway-helm-api.md
index 9f2046a537f..bb817b992dc 100644
--- a/site/content/en/docs/install/gateway-helm-api.md
+++ b/site/content/en/docs/install/gateway-helm-api.md
@@ -23,7 +23,7 @@ The Helm chart for Envoy Gateway
| Key | Type | Default | Description |
|-----|------|---------|-------------|
-| certgen | object | `{"job":{"annotations":{},"resources":{},"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
+| certgen | object | `{"job":{"affinity":{},"annotations":{},"nodeSelector":{},"resources":{},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsGroup":65534,"runAsNonRoot":true,"runAsUser":65534,"seccompProfile":{"type":"RuntimeDefault"}},"tolerations":[],"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
| config.envoyGateway.gateway.controllerName | string | `"gateway.envoyproxy.io/gatewayclass-controller"` | |
| config.envoyGateway.logging.level.default | string | `"info"` | |
| config.envoyGateway.provider.type | string | `"Kubernetes"` | |
@@ -32,14 +32,21 @@ The Helm chart for Envoy Gateway
| deployment.envoyGateway.image.tag | string | `""` | |
| deployment.envoyGateway.imagePullPolicy | string | `""` | |
| deployment.envoyGateway.imagePullSecrets | list | `[]` | |
-| deployment.envoyGateway.resources.limits.cpu | string | `"500m"` | |
| deployment.envoyGateway.resources.limits.memory | string | `"1024Mi"` | |
| deployment.envoyGateway.resources.requests.cpu | string | `"100m"` | |
| deployment.envoyGateway.resources.requests.memory | string | `"256Mi"` | |
+| deployment.envoyGateway.securityContext.allowPrivilegeEscalation | bool | `false` | |
+| deployment.envoyGateway.securityContext.capabilities.drop[0] | string | `"ALL"` | |
+| deployment.envoyGateway.securityContext.privileged | bool | `false` | |
+| deployment.envoyGateway.securityContext.runAsGroup | int | `65532` | |
+| deployment.envoyGateway.securityContext.runAsNonRoot | bool | `true` | |
+| deployment.envoyGateway.securityContext.runAsUser | int | `65532` | |
+| deployment.envoyGateway.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | |
| deployment.pod.affinity | object | `{}` | |
| deployment.pod.annotations."prometheus.io/port" | string | `"19001"` | |
| deployment.pod.annotations."prometheus.io/scrape" | string | `"true"` | |
| deployment.pod.labels | object | `{}` | |
+| deployment.pod.nodeSelector | object | `{}` | |
| deployment.pod.tolerations | list | `[]` | |
| deployment.pod.topologySpreadConstraints | list | `[]` | |
| deployment.ports[0].name | string | `"grpc"` | |
@@ -54,6 +61,7 @@ The Helm chart for Envoy Gateway
| deployment.ports[3].name | string | `"metrics"` | |
| deployment.ports[3].port | int | `19001` | |
| deployment.ports[3].targetPort | int | `19001` | |
+| deployment.priorityClassName | string | `nil` | |
| deployment.replicas | int | `1` | |
| global.images.envoyGateway.image | string | `nil` | |
| global.images.envoyGateway.pullPolicy | string | `nil` | |
@@ -63,4 +71,5 @@ The Helm chart for Envoy Gateway
| global.images.ratelimit.pullSecrets | list | `[]` | |
| kubernetesClusterDomain | string | `"cluster.local"` | |
| podDisruptionBudget.minAvailable | int | `0` | |
+| service.annotations | object | `{}` | |
diff --git a/site/content/en/docs/install/install-helm.md b/site/content/en/docs/install/install-helm.md
index 277856b9aac..16975efc84d 100644
--- a/site/content/en/docs/install/install-helm.md
+++ b/site/content/en/docs/install/install-helm.md
@@ -59,6 +59,12 @@ consideration when debugging.
[`quickstart.yaml`]: https://github.com/envoyproxy/gateway/releases/download/{{< yaml-version >}}/quickstart.yaml
+## Upgrading from a previous version
+
+[Helm](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations) does not update CRDs
+that live in the `/crds` folder in the Helm Chart. So you will manually need to update the CRDs.
+Follow the steps outlined in [this](./install-yaml/#upgrading-from-v1.1) section if you're upgrading from a previous version.
+
## Helm chart customizations
Some of the quick ways of using the helm install command for envoy gateway installation are below.
diff --git a/site/content/en/docs/install/install-yaml.md b/site/content/en/docs/install/install-yaml.md
index e675f15fbec..0da5ca9cca1 100644
--- a/site/content/en/docs/install/install-yaml.md
+++ b/site/content/en/docs/install/install-yaml.md
@@ -13,7 +13,7 @@ installation, it is recommended that you use helm.
Envoy Gateway is designed to run in Kubernetes for production. The most essential requirements are:
-* Kubernetes 1.25 or later
+* Kubernetes 1.28 or later
* The `kubectl` command-line tool
{{% alert title="Compatibility Matrix" color="warning" %}}
@@ -37,3 +37,24 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more.
2. Next Steps
Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks).
+
+## Upgrading from v1.1
+
+Some manual migration steps are required to upgrade Envoy Gateway to v1.2.
+
+1. Update your `GRPCRoute` and `ReferenceGrant` resources if the storage version being used is `v1alpha2`.
+Follow the steps in Gateway-API [v1.2 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v12-upgrade-notes)
+
+2. Update Gateway-API and Envoy Gateway CRDs:
+
+```shell
+helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-crds.yaml
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated
+```
+
+3. Install Envoy Gateway {{< yaml-version >}}:
+
+```shell
+helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system
+```
diff --git a/site/content/en/docs/install/migrating-to-envoy.md b/site/content/en/docs/install/migrating-to-envoy.md
new file mode 100644
index 00000000000..470c759ab7e
--- /dev/null
+++ b/site/content/en/docs/install/migrating-to-envoy.md
@@ -0,0 +1,143 @@
+---
+title: Migrating from Ingress Resources
+---
+
+## Introduction
+
+Migrating from Ingress to Envoy Gateway involves converting existing Ingress resources into resources compatible with Envoy Gateway. The `ingress2gateway` tool simplifies this migration by transforming Ingress resources into Gateway API resources that Envoy Gateway can use. This guide will walk you through the prerequisites, installation of the `ingress2gateway` tool, and provide an example migration process.
+
+## Prerequisites
+
+Before you start the migration, ensure you have the following:
+
+1. **Envoy Gateway Installed**: You need Envoy Gateway set up in your Kubernetes cluster. Follow the [Envoy Gateway installation guide](../install) for details.
+2. **Kubernetes Cluster Access**: Ensure you have access to your Kubernetes cluster and necessary permissions to manage resources.
+3. **Installation of `ingress2gateway` Tool**: You need to install the `ingress2gateway` tool in your Kubernetes cluster and configure it accordingly. Follow the [ingress2gateway tool installation guide](https://github.com/kubernetes-sigs/ingress2gateway/blob/main/README.md#installation) for details.
+
+## Example Migration
+
+Here’s a step-by-step example of migrating from Ingress to Envoy Gateway using `ingress2gateway`:
+
+### 1. Install and Configure Envoy Gateway
+
+Ensure that Envoy Gateway is installed and running in your cluster. Follow the [official Envoy Gateway installation guide](../install) for setup instructions.
+
+### 2. Create a GatewayClass
+
+To ensure the generated HTTPRoutes are programmed correctly in the Envoy Gateway data plane, create a GatewayClass that links to the Envoy Gateway controller.
+
+Create a `GatewayClass` resource:
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: GatewayClass
+metadata:
+ name: envoy-gateway-class
+spec:
+ controllerName: gateway.envoyproxy.io/controller
+```
+
+Apply this resource:
+
+```sh
+kubectl apply -f gatewayclass.yaml
+```
+
+### 3. Install Ingress2gateway
+
+Ensure you have the Ingress2gateway package installed. If not, follow the package’s installation instructions.
+
+### 4. Run Ingress2gateway
+
+Use Ingress2gateway to read your existing Ingress resources and translate them into Gateway API resources.
+
+```sh
+./ingress2gateway print
+```
+
+This command will:
+1. Read your Kube config file to extract the cluster credentials and the current active namespace.
+2. Search for Ingress and provider-specific resources in that namespace.
+3. Convert them to Gateway API resources (Gateways and HTTPRoutes).
+
+#### Example Ingress Configuration
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: example-ingress
+ namespace: default
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /
+spec:
+ rules:
+ - host: example.com
+ http:
+ paths:
+ - path: /foo
+ pathType: Prefix
+ backend:
+ service:
+ name: foo-service
+ port:
+ number: 80
+```
+
+### 5. Save the Output
+
+The command will output the equivalent Gateway API resources in YAML/JSON format to stdout. Save this output to a file for further use.
+
+```sh
+./ingress2gateway print > gateway-resources.yaml
+```
+
+### 6. Apply the Translated Resources
+
+Apply the translated Gateway API resources to your cluster.
+
+```sh
+kubectl apply -f gateway-resources.yaml
+```
+
+### 7. Create a Gateway Resource
+
+Create a `Gateway` resource specifying the `GatewayClass` created earlier and including the necessary listeners.
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: Gateway
+metadata:
+ name: example-gateway
+ namespace: default
+spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ hostname: example.com
+```
+
+Apply this resource:
+
+```sh
+kubectl apply -f gateway.yaml
+```
+
+### 8. Validate the Migration
+
+Ensure the HTTPRoutes and Gateways are correctly set up and that traffic is being routed as expected. Validate the new configuration by checking the status of the Gateway and HTTPRoute resources.
+
+```sh
+kubectl get gateways
+kubectl get httproutes
+```
+
+### 9. Monitor and Troubleshoot
+
+Monitor the Envoy Gateway logs and metrics to ensure everything is functioning correctly. Troubleshoot any issues by reviewing the Gateway and HTTPRoute statuses and Envoy Gateway controller logs.
+
+## Summary
+
+By following this guide, users can effectively migrate their existing Ingress resources to Envoy Gateway using the Ingress2gateway package. Creating a GatewayClass and linking it to the Envoy Gateway controller ensures that the translated resources are properly programmed in the data plane, providing a seamless transition to the Envoy Gateway environment.
\ No newline at end of file
diff --git a/site/content/en/docs/tasks/extensibility/envoy-patch-policy.md b/site/content/en/docs/tasks/extensibility/envoy-patch-policy.md
index ff819754d1f..9fddf7dc576 100644
--- a/site/content/en/docs/tasks/extensibility/envoy-patch-policy.md
+++ b/site/content/en/docs/tasks/extensibility/envoy-patch-policy.md
@@ -22,8 +22,7 @@ not exposed by Envoy Gateway APIs today.
### Prerequisites
-* Follow the steps from the [Quickstart](../../quickstart) task to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
### Enable EnvoyPatchPolicy
@@ -81,11 +80,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-* After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
## Testing
@@ -111,7 +106,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -151,7 +145,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -195,7 +188,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -235,7 +227,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -273,12 +264,91 @@ kubectl patch httproute backend --type=json --patch '
* Test it out by specifying a path apart from `/get`
-```
-$ curl --header "Host: www.example.com" http://localhost:8888/find
+```shell
+$ curl --header "Host: www.example.com" http://$GATEWAY_HOST/find
Handling connection for 8888
could not find what you are looking for
```
+### Customize VirtualHost by name
+
+* Use EnvoyProxy's `include_attempt_count_in_response` feature to include the attempt count as header in the downstream response.
+* Apply the configuration
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <//
+ name: default/eg/http
+ operation:
+ op: add
+ # Every virtual_host that ends with 'www_example_com' (using RegEx Filter)
+ jsonPath: "..virtual_hosts[?match(@.name, '.*www_example_com')]"
+ # If the property does not exists, it can not be selected with jsonPath
+ # Therefore the new property must be set in path
+ path: "include_attempt_count_in_response"
+ value: true
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyPatchPolicy
+metadata:
+ name: include-attempts
+ namespace: default
+spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
+ type: JSONPatch
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
+ # The RouteConfiguration name is of the form //
+ name: default/eg/http
+ operation:
+ op: add
+ # Every virtual_host that ends with 'www_example_com' (using RegEx Filter)
+ jsonPath: "..virtual_hosts[?match(@.name, '.*www_example_com')]"
+ # If the property does not exists, it can not be selected with jsonPath
+ # Therefore the new property must be set in path
+ path: "include_attempt_count_in_response"
+ value: true
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+* Test it out by looking at the response headers
+
+```
+$ curl -v --header "Host: www.example.com" http://localhost:8888/
+...
+< x-envoy-attempt-count: 1
+...
+```
+
## Debugging
### Runtime
@@ -322,7 +392,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
status:
conditions:
@@ -345,7 +414,7 @@ status:
## Caveats
-This API will always be an unstable API and the same outcome cannot be garunteed
+This API will always be an unstable API and the same outcome cannot be guaranteed
across versions for these reasons
* The Envoy Proxy API might deprecate and remove API fields
* Envoy Gateway might alter the xDS translation creating a different xDS output
diff --git a/site/content/en/docs/tasks/extensibility/ext-proc.md b/site/content/en/docs/tasks/extensibility/ext-proc.md
index 9028447ab09..910332f4740 100644
--- a/site/content/en/docs/tasks/extensibility/ext-proc.md
+++ b/site/content/en/docs/tasks/extensibility/ext-proc.md
@@ -12,14 +12,7 @@ This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute]
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
-
-Verify the Gateway status:
-
-```shell
-kubectl get gateway/eg -o yaml
-```
+{{< boilerplate prerequisites >}}
## GRPC External Processing Service
@@ -113,10 +106,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
@@ -139,10 +132,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
diff --git a/site/content/en/docs/tasks/extensibility/extension-server.md b/site/content/en/docs/tasks/extensibility/extension-server.md
index 7d67c23f6da..6d16013d410 100644
--- a/site/content/en/docs/tasks/extensibility/extension-server.md
+++ b/site/content/en/docs/tasks/extensibility/extension-server.md
@@ -1,5 +1,6 @@
---
title: "Envoy Gateway Extension Server"
+linkTitle: "Extension Server"
---
This task explains how to extend Envoy Gateway using an Extension Server. Envoy Gateway
@@ -37,8 +38,7 @@ Authentication.
### Prerequisites
-* Follow the steps from the [Quickstart](../quickstart) task to install Envoy Gateway and the example manifest.
- Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
### Build and run the example Extension Server
diff --git a/site/content/en/docs/tasks/extensibility/wasm.md b/site/content/en/docs/tasks/extensibility/wasm.md
index d973de77950..baad6a5804f 100644
--- a/site/content/en/docs/tasks/extensibility/wasm.md
+++ b/site/content/en/docs/tasks/extensibility/wasm.md
@@ -12,18 +12,11 @@ This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute]
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
-
-Verify the Gateway status:
-
-```shell
-kubectl get gateway/eg -o yaml
-```
+{{< boilerplate prerequisites >}}
## Configuration
-Envoy Gateway supports two types of Wasm extensions:
+Envoy Gateway supports two types of Wasm extensions:
* HTTP Wasm Extension: The Wasm extension is fetched from a remote URL.
* Image Wasm Extension: The Wasm extension is packaged as an OCI image and fetched from an image registry.
@@ -44,8 +37,8 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
@@ -54,7 +47,7 @@ spec:
code:
type: HTTP
http:
- url: https://raw.githubusercontent.com/envoyproxy/envoy/main/examples/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
+ url: https://raw.githubusercontent.com/envoyproxy/examples/main/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0
EOF
```
@@ -70,18 +63,18 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
- - name: wasm-filter
- rootID: my_root_id
- code:
- type: HTTP
- http:
- url: https://raw.githubusercontent.com/envoyproxy/envoy/main/examples/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
- sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0
+ - name: wasm-filter
+ rootID: my_root_id
+ code:
+ type: HTTP
+ http:
+ url: https://raw.githubusercontent.com/envoyproxy/examples/main/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
+ sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0
```
{{% /tab %}}
@@ -107,8 +100,8 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
@@ -132,17 +125,17 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
- - name: wasm-filter
- rootID: my_root_id
- code:
- type: Image
- image:
- url: zhaohuabing/testwasm:v0.0.1
+ - name: wasm-filter
+ rootID: my_root_id
+ code:
+ type: Image
+ image:
+ url: zhaohuabing/testwasm:v0.0.1
```
{{% /tab %}}
diff --git a/site/content/en/docs/tasks/observability/gateway-api-metrics.md b/site/content/en/docs/tasks/observability/gateway-api-metrics.md
index bd9e5b89317..bf799616aff 100644
--- a/site/content/en/docs/tasks/observability/gateway-api-metrics.md
+++ b/site/content/en/docs/tasks/observability/gateway-api-metrics.md
@@ -7,8 +7,7 @@ The project also provides example dashboard for visualising the metrics using Gr
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
Run the following commands to install the metrics stack, with the Gateway API State Metrics configuration, on your kubernetes cluster:
diff --git a/site/content/en/docs/tasks/observability/gateway-observability.md b/site/content/en/docs/tasks/observability/gateway-observability.md
index 6e0040b4f5d..f23eb9097cf 100644
--- a/site/content/en/docs/tasks/observability/gateway-observability.md
+++ b/site/content/en/docs/tasks/observability/gateway-observability.md
@@ -86,11 +86,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in:
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
### Enable Open Telemetry sink in Envoy Gateway
@@ -157,11 +153,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in:
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
Verify OTel-Collector metrics:
diff --git a/site/content/en/docs/tasks/observability/proxy-accesslog.md b/site/content/en/docs/tasks/observability/proxy-accesslog.md
index fb0200f1739..17d444b8636 100644
--- a/site/content/en/docs/tasks/observability/proxy-accesslog.md
+++ b/site/content/en/docs/tasks/observability/proxy-accesslog.md
@@ -249,3 +249,62 @@ Envoy Gateway provides additional metadata about the K8s resources that were tra
For example, details about the `HTTPRoute` and `GRPCRoute` (kind, group, name, namespace and annotations) are available
for access log formatter using the `METADATA` operator. To enrich logs, users can add log operator such as:
`%METADATA(ROUTE:envoy-gateway:resources)%` to their access log format.
+
+## Access Log Types
+
+By default, Access Log settings would apply to:
+- All Routes
+- If traffic is not matched by any Route known to Envoy, the Listener would emit the access log instead
+
+Users may wish to customize this behavior:
+- Emit Access Logs by all Listeners for all traffic with specific settings
+- Do not emit Route-oriented access logs when a route is not matched.
+
+To achieve this, users can select if Access Log settings follow the default behavior or apply specifically to
+Routes or Listeners by specifying the setting's type.
+
+**Note**: When users define their own Access Log settings (with or without a type), the default Envoy Gateway
+file access log is no longer configured. It can be re-enabled explicitly by adding empty settings for the desired components.
+
+In the following example:
+- Route Access logs would use the default Envoy Gateway format and sink
+- Listener Access logs are customized to report transport-level failures and connection attributes
+
+```shell
+kubectl apply -f - <}}
diff --git a/site/content/en/docs/tasks/observability/rate-limit-observability.md b/site/content/en/docs/tasks/observability/rate-limit-observability.md
index a0e523d6c8a..ec1244f731e 100644
--- a/site/content/en/docs/tasks/observability/rate-limit-observability.md
+++ b/site/content/en/docs/tasks/observability/rate-limit-observability.md
@@ -91,8 +91,4 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-After updating the ConfigMap, you will need to restart the envoy-gateway deployment so the configuration kicks in:
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
diff --git a/site/content/en/docs/tasks/operations/customize-envoyproxy.md b/site/content/en/docs/tasks/operations/customize-envoyproxy.md
index 562237bfc43..9c5ab5fe177 100644
--- a/site/content/en/docs/tasks/operations/customize-envoyproxy.md
+++ b/site/content/en/docs/tasks/operations/customize-envoyproxy.md
@@ -3,15 +3,68 @@ title: "Customize EnvoyProxy"
---
Envoy Gateway provides an [EnvoyProxy][] CRD that can be linked to the ParametersRef
-in GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
+in a Gateway and GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
Service. To learn more about GatewayClass and ParametersRef, please refer to [Gateway API documentation][].
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
-Before you start, you need to add `ParametersRef` in GatewayClass, and refer to EnvoyProxy Config:
+Before you start, you need to add `Infrastructure.ParametersRef` in Gateway, and refer to EnvoyProxy Config:
+**Note**: `MergeGateways` cannot be set to `true` in your EnvoyProxy config if attaching to the Gateway.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+You can also attach the EnvoyProxy resource to the GatewayClass using the `parametersRef` field.
+This configuration is discouraged if you plan on creating multiple Gateways linking to the same
+GatewayClass and would like different infrastructure configurations for each of them.
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -28,7 +81,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
EOF
```
@@ -48,7 +101,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
```
{{% /tab %}}
@@ -67,7 +120,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -87,7 +140,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -119,7 +172,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -140,7 +193,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -168,7 +221,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -191,7 +244,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -221,7 +274,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -248,7 +301,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -280,7 +333,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -305,7 +358,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -339,7 +392,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -368,7 +421,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -404,7 +457,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -426,7 +479,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -445,13 +498,14 @@ After applying the config, you can get the envoyproxy service, and see annotatio
## Customize EnvoyProxy Bootstrap Config
You can customize the EnvoyProxy bootstrap config via EnvoyProxy Config.
-There are two ways to customize it:
+There are three ways to customize it:
* Replace: the whole bootstrap config will be replaced by the config you provided.
* Merge: the config you provided will be merged into the default bootstrap config.
+* JSONPatch: the list of JSON Patches you provided will be applied to the bootstrap config. JSON Patch is a standard format specified in [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902/).
{{< tabpane text=true >}}
-{{% tab header="Apply from stdin" %}}
+{{% tab header="Replace: apply from stdin" %}}
```shell
cat <}}
-You can use [egctl translate][]
+You can use [egctl x translate][]
to get the default xDS Bootstrap configuration used by Envoy Gateway.
After applying the config, the bootstrap config will be overridden by the new config you provided.
Any errors in the configuration will be surfaced as status within the `GatewayClass` resource.
-You can also validate this configuration using [egctl translate][].
+You can also validate this configuration using [egctl x translate][].
## Customize EnvoyProxy Horizontal Pod Autoscaler
@@ -649,7 +742,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -677,7 +770,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -713,7 +806,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -730,7 +823,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -756,7 +849,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -792,7 +885,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -835,7 +928,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -860,7 +953,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -918,7 +1011,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
@@ -938,7 +1031,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
@@ -950,6 +1043,53 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
+## Customize EnvoyProxy IP Family
+
+You can customize the IP family configuration for EnvoyProxy via the EnvoyProxy Config.
+This allows the Envoy Proxy fleet to serve external clients over IPv4 as well as IPv6.
+
+The below configuration sets the `ipFamily` to `DualStack` to allow ingressing IPv4 as well as IPv6 traffic.
+
+**Note**: Envoy Gateway relies on the [Service](https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services) spec of the BackendRef resource (linked to xRoutes) to decide which type of IP addresses to use to route to them.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After applying the config, the EnvoyProxy deployment will be configured to use the specified IP family. When set to `DualStack`, both IPv4 and IPv6 networking will be enabled.
+
+**Note**: Your cluster must support the selected IP family configuration. For DualStack support, ensure your Kubernetes cluster is properly configured for dual-stack networking.
+
[Gateway API documentation]: https://gateway-api.sigs.k8s.io/
[EnvoyProxy]: ../../../api/extension_types#envoyproxy
-[egctl translate]: ../egctl/#validating-gateway-api-configuration
+[egctl x translate]: ../operations/egctl#egctl-experimental-translate
\ No newline at end of file
diff --git a/site/content/en/docs/tasks/operations/egctl.md b/site/content/en/docs/tasks/operations/egctl.md
index ac1f13d7a61..36c1f9979e2 100644
--- a/site/content/en/docs/tasks/operations/egctl.md
+++ b/site/content/en/docs/tasks/operations/egctl.md
@@ -4,8 +4,6 @@ title: "Use egctl"
`egctl` is a command line tool to provide additional functionality for Envoy Gateway users.
-
-
## egctl experimental translate
This subcommand allows users to translate from an input configuration type to an output configuration type.
diff --git a/site/content/en/docs/tasks/operations/standalone-deployment-mode.md b/site/content/en/docs/tasks/operations/standalone-deployment-mode.md
new file mode 100644
index 00000000000..cc8218a2905
--- /dev/null
+++ b/site/content/en/docs/tasks/operations/standalone-deployment-mode.md
@@ -0,0 +1,123 @@
+---
+title: "Standalone Deployment Mode"
+---
+
+{{% alert title="Notice" color="warning" %}}
+
+Standalone mode is an experimental feature, please **DO NOT** use it in production.
+
+{{% /alert %}}
+
+Envoy Gateway also supports running in standalone mode. In this mode, Envoy Gateway
+does not need to rely on Kubernetes and can be deployed directly on bare metal or virtual machines.
+
+Currently, Envoy Gateway only support the file provider and the host infrastructure provider combinations.
+
+- The file provider will configure the Envoy Gateway to get all gateway-api resources from file system.
+- The host infrastructure provider will configure the Envoy Gateway to deploy one Envoy Proxy as a host process.
+
+## Quick Start
+
+In this quick-start, we will run Envoy Gateway in standalone mode with the file provider
+and the host infrastructure provider.
+
+### Prerequisites
+
+Create a local directory just for testing:
+
+```shell
+mkdir -p /tmp/envoy-gateway-test
+```
+
+Download the Envoy Gateway binary from v1.2.x release.
+
+### Create Certificates
+
+All runners in Envoy Gateway are using TLS connection, so create these TLS certificates locally to
+ensure the Envoy Gateway works properly.
+
+```shell
+envoy-gateway certgen --local
+```
+
+### Start Envoy Gateway
+
+Start Envoy Gateway by the following command:
+
+```shell
+envoy-gateway server --config-path standalone.yaml
+```
+
+with `standalone.yaml` configuration:
+
+```yaml
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyGateway
+gateway:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+provider:
+ type: Custom
+ custom:
+ resource:
+ type: File
+ file:
+ paths: ["/tmp/envoy-gateway-test"]
+ infrastructure:
+ type: Host
+ host: {}
+logging:
+ level:
+ default: info
+extensionApis:
+ enableBackend: true
+```
+
+As you can see, we have enabled the [Backend][] API, this API will be used to represent our local endpoints.
+
+### Trigger an Update
+
+Any changes under watched `paths` will be considered as an update by the file provider.
+
+For instance, copying example file into `/tmp/envoy-gateway-test/` will trigger an update of gateway-api resources:
+
+```shell
+cp examples/standalone/quickstart.yaml /tmp/envoy-gateway-test/quickstart.yaml
+```
+
+From the Envoy Gateway log, you should be able to observe that the Envoy Proxy has been started, and its admin address has been returned.
+
+### Test Connection
+
+Starts a simple local server as an endpoint:
+
+```shell
+python3 -m http.server 3000
+```
+
+Curl the example server through Envoy Proxy:
+
+```shell
+curl --verbose --header "Host: www.example.com" http://0.0.0.0:8888/
+```
+
+```console
+* Trying 0.0.0.0:8888...
+* Connected to 0.0.0.0 (127.0.0.1) port 8888 (#0)
+> GET / HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/7.81.0
+> Accept: */*
+>
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 200 OK
+< server: SimpleHTTP/0.6 Python/3.10.12
+< date: Sat, 26 Oct 2024 13:20:34 GMT
+< content-type: text/html; charset=utf-8
+< content-length: 1870
+<
+...
+* Connection #0 to host 0.0.0.0 left intact
+```
+
+
+[Backend]: ../../../api/extension_types#backend
diff --git a/site/content/en/docs/tasks/quickstart.md b/site/content/en/docs/tasks/quickstart.md
index 03d7b6de842..e1943c21e92 100644
--- a/site/content/en/docs/tasks/quickstart.md
+++ b/site/content/en/docs/tasks/quickstart.md
@@ -12,7 +12,7 @@ A Kubernetes cluster.
__Note:__ Refer to the [Compatibility Matrix](/news/releases/matrix) for supported Kubernetes versions.
-__Note:__ In case your Kubernetes cluster, does not have a LoadBalancer implementation, we recommend installing one
+__Note:__ In case your Kubernetes cluster does not have a LoadBalancer implementation, we recommend installing one
so the `Gateway` resource has an Address associated with it. We recommend using [MetalLB](https://metallb.universe.tf/installation/).
__Note:__ For Mac user, you need install and run [Docker Mac Net Connect](https://github.com/chipmk/docker-mac-net-connect) to make the Docker network work.
@@ -92,34 +92,6 @@ curl --verbose --header "Host: www.example.com" http://localhost:8888/get
{{% /tab %}}
{{< /tabpane >}}
-## v1.1 Upgrade Notes
-
-Due to breaking changes in the Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1.
-
-Delete `BackendTLSPolicy` CRD (and resources):
-
-```shell
-kubectl delete crd backendtlspolicies.gateway.networking.k8s.io
-```
-
-Update Gateway-API and Envoy Gateway CRDs:
-
-```shell
-helm pull oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 --untar
-kubectl apply -f ./gateway-helm/crds/gatewayapi-crds.yaml
-kubectl apply -f ./gateway-helm/crds/generated
-```
-
-Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes)
-
-Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef.
-
-Install Envoy Gateway v1.1.0:
-
-```shell
-helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system
-```
-
## What to explore next?
In this quickstart, you have:
diff --git a/site/content/en/docs/tasks/security/backend-tls.md b/site/content/en/docs/tasks/security/backend-tls.md
index 53e9ccbd44a..945a1f5ff98 100644
--- a/site/content/en/docs/tasks/security/backend-tls.md
+++ b/site/content/en/docs/tasks/security/backend-tls.md
@@ -13,11 +13,11 @@ Envoy Gateway supports the Gateway-API defined [BackendTLSPolicy][].
## Installation
-Follow the steps from the [Quickstart][] to install Envoy Gateway and the example manifest.
+{{< boilerplate prerequisites >}}
## TLS Certificates
-Generate the certificates and keys used by the backend to terminate TLS connections from the Gateways.
+Generate the certificates and keys used by the backend to terminate TLS connections from the Gateways.
Create a root certificate and private key to sign certificates:
@@ -25,11 +25,30 @@ Create a root certificate and private key to sign certificates:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout ca.key -out ca.crt
```
-Create a certificate and a private key for `www.example.com`:
+Create a certificate and a private key for `www.example.com`.
+
+First, create an openssl configuration file:
```shell
-openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization" -addext "subjectAltName = DNS:www.example.com"
-openssl x509 -req -days 365 -CA ca.crt -CAkey ca.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt
+cat > openssl.conf <}}
{{% tab header="Apply from stdin" %}}
@@ -136,6 +155,9 @@ spec:
Create a [BackendTLSPolicy][] instructing Envoy Gateway to establish a TLS connection with the backend and validate the backend certificate is issued by a trusted CA and contains an appropriate DNS SAN.
+Note: SectionName is an optional field that specifies the name of the port in the target backend. This example uses a Kubernetes Service as the backend target, so the sectionName is set to `https` to match the port name in the Service.
+If the target is a [Backend] resource, the `sectionName` field should be set to the port number of the backend.
+
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -151,7 +173,7 @@ spec:
- group: ''
kind: Service
name: tls-backend
- sectionName: "443"
+ sectionName: https
validation:
caCertificateRefs:
- name: example-ca
@@ -177,7 +199,7 @@ spec:
- group: ''
kind: Service
name: tls-backend
- sectionName: "443"
+ sectionName: https
validation:
caCertificateRefs:
- name: example-ca
@@ -279,8 +301,8 @@ Inspect the output and see that the response contains the details of the TLS han
## Customize backend TLS Parameters
-In addition to enablement of backend TLS with the Gateway-API BackendTLSPolicy, Envoy Gateway supports customizing TLS parameters.
-To achieve this, the [EnvoyProxy][] resource can be used to specify TLS parameters. We will customize the TLS version in this example.
+In addition to enablement of backend TLS with the Gateway-API BackendTLSPolicy, Envoy Gateway supports customizing TLS parameters.
+To achieve this, the [EnvoyProxy][] resource can be used to specify TLS parameters. We will customize the TLS version in this example.
First, you need to add ParametersRef in GatewayClass, and refer to EnvoyProxy Config:
@@ -371,7 +393,7 @@ curl -v -HHost:www.example.com --resolve "www.example.com:80:127.0.0.1" \
http://www.example.com:80/get
```
-Inspect the output and see that the response contains the details of the TLS handshake between Envoy and the backend.
+Inspect the output and see that the response contains the details of the TLS handshake between Envoy and the backend.
The TLS version is now TLS1.3, as configured in the EnvoyProxy resource. The TLS cipher is also changed, since TLS1.3 supports different ciphers from TLS1.2.
```shell
@@ -385,6 +407,6 @@ The TLS version is now TLS1.3, as configured in the EnvoyProxy resource. The TLS
}
```
-[Quickstart]: ../quickstart
[BackendTLSPolicy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
-[EnvoyProxy]: ../../api/extension_types#envoyproxy
\ No newline at end of file
+[EnvoyProxy]: ../../api/extension_types#envoyproxy
+[Backend]: ../../api/extension_types#backend
diff --git a/site/content/en/docs/tasks/security/basic-auth.md b/site/content/en/docs/tasks/security/basic-auth.md
index 956963b6da5..cc0ec54ada1 100644
--- a/site/content/en/docs/tasks/security/basic-auth.md
+++ b/site/content/en/docs/tasks/security/basic-auth.md
@@ -12,8 +12,7 @@ This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HT
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Configuration
@@ -110,10 +109,10 @@ kind: SecurityPolicy
metadata:
name: basic-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
basicAuth:
users:
name: "basic-auth"
@@ -131,10 +130,10 @@ kind: SecurityPolicy
metadata:
name: basic-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
basicAuth:
users:
name: "basic-auth"
@@ -195,7 +194,6 @@ curl -kv -H "Host: www.example.com" -u 'foo:bar' "https://${GATEWAY_HOST}/"
The request should be allowed and you should see the response from the backend service.
-```shell
## Clean-Up
diff --git a/site/content/en/docs/tasks/security/cors.md b/site/content/en/docs/tasks/security/cors.md
index cfbe979cd22..90a972ce4ca 100644
--- a/site/content/en/docs/tasks/security/cors.md
+++ b/site/content/en/docs/tasks/security/cors.md
@@ -11,8 +11,7 @@ This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HT
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Configuration
@@ -32,8 +31,8 @@ kind: SecurityPolicy
metadata:
name: cors-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
cors:
@@ -63,8 +62,8 @@ kind: SecurityPolicy
metadata:
name: cors-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
cors:
diff --git a/site/content/en/docs/tasks/security/ext-auth.md b/site/content/en/docs/tasks/security/ext-auth.md
index 5fc73321106..1d1625d5780 100644
--- a/site/content/en/docs/tasks/security/ext-auth.md
+++ b/site/content/en/docs/tasks/security/ext-auth.md
@@ -13,14 +13,7 @@ This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute]
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
-
-Verify the Gateway status:
-
-```shell
-kubectl get gateway/eg -o yaml
-```
+{{< boilerplate prerequisites >}}
## HTTP External Authorization Service
@@ -110,15 +103,15 @@ kind: SecurityPolicy
metadata:
name: ext-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extAuth:
http:
- backendRef:
- name: http-ext-auth
- port: 9002
+ backendRefs:
+ - name: http-ext-auth
+ port: 9002
headersToBackend: ["x-current-user"]
EOF
```
@@ -134,15 +127,15 @@ kind: SecurityPolicy
metadata:
name: ext-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extAuth:
http:
- backendRef:
- name: http-ext-auth
- port: 9002
+ backendRefs:
+ - name: http-ext-auth
+ port: 9002
headersToBackend: ["x-current-user"]
```
@@ -296,15 +289,15 @@ kind: SecurityPolicy
metadata:
name: ext-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extAuth:
grpc:
- backendRef:
- name: grpc-ext-auth
- port: 9002
+ backendRefs:
+ - name: grpc-ext-auth
+ port: 9002
EOF
```
@@ -319,15 +312,15 @@ kind: SecurityPolicy
metadata:
name: ext-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extAuth:
grpc:
- backendRef:
- name: grpc-ext-auth
- port: 9002
+ backendRefs:
+ - name: grpc-ext-auth
+ port: 9002
```
{{% /tab %}}
diff --git a/site/content/en/docs/tasks/security/jwt-authentication.md b/site/content/en/docs/tasks/security/jwt-authentication.md
index 8b160403882..e4361b6354f 100644
--- a/site/content/en/docs/tasks/security/jwt-authentication.md
+++ b/site/content/en/docs/tasks/security/jwt-authentication.md
@@ -11,9 +11,9 @@ This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HT
## Prerequisites
-Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway and the example manifest.
+{{< boilerplate prerequisites >}}
+
For GRPC - follow the steps from the [GRPC Routing](../traffic/grpc-routing) example.
-Before proceeding, you should be able to query the example backend using HTTP or GRPC.
## Configuration
@@ -91,7 +91,7 @@ A `401` HTTP response code should be returned.
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
__Note:__ The above command decodes and returns the token's payload. You can replace `f2` with `f1` to view the token's
@@ -128,7 +128,7 @@ Error invoking method "yages.Echo/Ping": rpc error: code = Unauthenticated desc
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
__Note:__ The above command decodes and returns the token's payload. You can replace `f2` with `f1` to view the token's
diff --git a/site/content/en/docs/tasks/security/jwt-claim-authorization.md b/site/content/en/docs/tasks/security/jwt-claim-authorization.md
new file mode 100644
index 00000000000..2e67ea7ffe9
--- /dev/null
+++ b/site/content/en/docs/tasks/security/jwt-claim-authorization.md
@@ -0,0 +1,226 @@
+---
+title: "JWT Claim-Based Authorization"
+---
+
+This task provides instructions for configuring JWT claim-based authorization. JWT claim-based authorization checks if an incoming request has the required JWT claims before routing the request to a backend service.
+
+Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure JWT claim-based authorization.
+
+This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HTTPRoute] or [GRPCRoute][GRPCRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## Configuration
+
+### Create a SecurityPolicy
+
+Please note that the JWT claim-based authorization requires the JWT token to be present in the request. A JWT authentication must be configured in the same SecurityPolicy to validate the JWT token and extract the claims.
+
+The below SecurityPolicy configuration allows requests with a valid JWT token that has the following claims:
+- `user.name` claim with the value `John Doe`
+- `user.roles` claim with the value `admin`
+- `scope` claim with the values `read`, `add`, and `modify`
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/authorization-jwt-claim -o yaml
+```
+
+## Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+Define a JWT token with the required claims.
+
+```shell
+export VALID_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImI1MjBiM2MyYzRiZDc1YTEwZTljZWJjOTU3NjkzM2RjIn0.eyJpc3MiOiJodHRwczovL2Zvby5iYXIuY29tIiwic3ViIjoiMTIzNDU2Nzg5MCIsInVzZXIiOnsibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqb2huLmRvZUBleGFtcGxlLmNvbSIsInJvbGVzIjpbImFkbWluIiwiZWRpdG9yIl19LCJwcmVtaXVtX3VzZXIiOnRydWUsImlhdCI6MTUxNjIzOTAyMiwic2NvcGUiOiJyZWFkIGFkZCBkZWxldGUgbW9kaWZ5In0.P36iAlmiRCC79OiB3vstF5Q_9OqUYAMGF3a3H492GlojbV6DcuOz8YIEYGsRSWc-BNJaBKlyvUKsKsGVPtYbbF8ajwZTs64wyO-zhd2R8riPkg_HsW7iwGswV12f5iVRpfQ4AG2owmdOToIaoch0aym89He1ZzEjcShr9olgqlAbbmhnk-namd1rP-xpzPnWhhIVI3mCz5hYYgDTMcM7qbokM5FzFttTRXAn5_Luor23U1062Ct_K53QArwxBvwJ-QYiqcBycHf-hh6sMx_941cUswrZucCpa-EwA3piATf9PKAyeeWHfHV9X-y8ipGOFg3mYMMVBuUZ1lBkJCik9f9kboRY6QzpOISARQj9PKMXfxZdIPNuGmA7msSNAXQgqkvbx04jMwb9U7eCEdGZztH4C8LhlRjgj0ZdD7eNbRjeH2F6zrWyMUpGWaWyq6rMuP98W2DWM5ZflK6qvT1c7FuFsWPvWLkgxQwTWQKrHdKwdbsu32Sj8VtUBJ0-ddEb"
+```
+
+Decode the JWT token to verify that it has the required claims.
+
+```shell
+jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< $(echo ${VALID_TOKEN})
+```
+
+The decoded JWT token should look like the following:
+
+```json
+{
+ "typ": "JWT",
+ "alg": "RS256",
+ "kid": "b520b3c2c4bd75a10e9cebc9576933dc"
+}
+{
+ "iss": "https://foo.bar.com",
+ "sub": "1234567890",
+ "user": {
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "roles": [
+ "admin",
+ "editor"
+ ]
+ },
+ "premium_user": true,
+ "iat": 1516239022,
+ "scope": "read add delete modify"
+}
+```
+
+Send a request to the backend service with the valid JWT token:
+
+```shell
+curl -H "Host: www.example.com" -H "Authorization: Bearer ${VALID_TOKEN}" "http://${GATEWAY_HOST}/"
+```
+
+The request should be allowed and you should see the response from the backend service.
+
+Define a JWT token without the required claims.
+
+```shell
+export INVALID_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImI1MjBiM2MyYzRiZDc1YTEwZTljZWJjOTU3NjkzM2RjIn0.eyJpc3MiOiJodHRwczovL2Zvby5iYXIuY29tIiwic3ViIjoiMTIzNDU2Nzg5MCIsInVzZXIiOnsibmFtZSI6IkFsaWNlIFNtaXRoIiwiZW1haWwiOiJhbGljZS5zbWl0aEBleGFtcGxlLmNvbSIsInJvbGVzIjpbImRldmVsb3BlciJdfSwicHJlbWl1bV91c2VyIjpmYWxzZSwiaWF0IjoxNTE2MjM5MDIyLCJzY29wZSI6InJlYWQgYWRkIGRlbGV0ZSJ9.Da547nNXzuQXm5E7LuLAiyFswXsW4RDhuitD_rpadtR7PTwzzOsJoqrVWJ_u1jJDaOTWIpLF4gwxDoY-Aoz_couzXzlAbECLs45ZFoc_UdffpfIbGKqTZx8VtwKuDLFsAeDDDqqx1flxFhvXHftJJdZYr1FgFz9u-absMmRU90DLmEZX3Hnyc8k8eBgeiu6vsWUD0-aNy8cWkFRbwRggkGmucFyUTG8Z1MY3iyH5E66W-ISoX8G9bzE9PTxVAAPDTvefD5iLJPSDJ8qV69OuMCJ8Dczq0L9Dd_w0sF-D1s9MTvexmGg4zBWluJ3r-pU9NHEdhqBypehp_yH8xF5Rt9AE7stZ4oPFZNyfrtkE-4IOnSEkMmzcC65g_rscn0ycerv4N5ZNpkr0x2IYYM4iGuo-ULv5Htnli3rffST45kx1XA8cdsrT1D0K3aPxdIxDIk8sTJf5-WVqRyo-bwxXXltwQLB9jCM_7QbTWQBYAJwUpi-0RW4jCl44-42gZnXf"
+```
+
+Decode the JWT token to verify that it does not have the required claims.
+
+```shell
+jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< $(echo ${INVALID_TOKEN})
+```
+
+The decoded JWT token should look like the following:
+
+```json
+{
+ "typ": "JWT",
+ "alg": "RS256",
+ "kid": "b520b3c2c4bd75a10e9cebc9576933dc"
+}
+{
+ "iss": "https://foo.bar.com",
+ "sub": "1234567890",
+ "user": {
+ "name": "Alice Smith",
+ "email": "alice.smith@example.com",
+ "roles": [
+ "developer"
+ ]
+ },
+ "premium_user": false,
+ "iat": 1516239022,
+ "scope": "read add delete"
+}
+```
+
+Send a request to the backend service with the invalid JWT token:
+
+```shell
+curl -v -H "Host: www.example.com" -H "Authorization: Bearer ${INVALID_TOKEN}" "http://${GATEWAY_HOST}/"
+```
+
+The request should be denied and you should see a `403 Forbidden` response.
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the SecurityPolicy and the ClientTrafficPolicy
+
+```shell
+kubectl delete securitypolicy/authorization-jwt-claim
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[SecurityPolicy]: ../../../contributions/design/security-policy
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[GRPCRoute]: https://gateway-api.sigs.k8s.io/api-types/grpcroute
diff --git a/site/content/en/docs/tasks/security/mutual-tls.md b/site/content/en/docs/tasks/security/mutual-tls.md
index 64f471ba19d..4ac9f96430a 100644
--- a/site/content/en/docs/tasks/security/mutual-tls.md
+++ b/site/content/en/docs/tasks/security/mutual-tls.md
@@ -11,8 +11,7 @@ This task uses a self-signed CA, so it should be used for testing and demonstrat
## Installation
-Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## TLS Certificates
@@ -89,11 +88,10 @@ metadata:
name: enable-mtls
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
tls:
clientValidation:
caCertificateRefs:
@@ -115,11 +113,10 @@ metadata:
name: enable-mtls
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
tls:
clientValidation:
caCertificateRefs:
diff --git a/site/content/en/docs/tasks/security/oidc.md b/site/content/en/docs/tasks/security/oidc.md
index ac7d6d60ba9..d57e7d35ff3 100644
--- a/site/content/en/docs/tasks/security/oidc.md
+++ b/site/content/en/docs/tasks/security/oidc.md
@@ -13,8 +13,7 @@ This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute]
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
EG OIDC authentication requires the redirect URL to be HTTPS. Follow the [Secure Gateways](../secure-gateways) guide
to generate the TLS certificates and update the Gateway configuration to add an HTTPS listener.
@@ -86,7 +85,7 @@ kubectl get httproute/myapp -o yaml
## OIDC Authentication for a HTTPRoute
-OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with
+OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with
the same OIDC configuration, or at the HTTPRoute level to authenticate each HTTPRoute with different OIDC configurations.
This section demonstrates how to configure OIDC authentication for a specific HTTPRoute.
@@ -98,7 +97,7 @@ providers, including Auth0, Azure AD, Keycloak, Okta, OneLogin, Salesforce, UAA,
Follow the steps in the [Google OIDC documentation][google-oidc] to register an OIDC application. Please make sure the
redirect URL is set to the one you configured in the SecurityPolicy that you will create in the step below. In this example,
-the redirect URL is `http://www.example.com:8443/myapp/oauth2/callback`.
+the redirect URL is `https://www.example.com:8443/myapp/oauth2/callback`.
After registering the application, you should have the following information:
* Client ID: The client ID of the OIDC application.
@@ -118,9 +117,9 @@ kubectl create secret generic my-app-client-secret --from-literal=client-secret=
### Create a SecurityPolicy
**Please notice that the `redirectURL` and `logoutPath` must match the target HTTPRoute.** In this example, the target
-HTTPRoute is configured to match the host `www.example.com` and the path `/myapp`, so the `redirectURL` must be prefixed
-with `https://www.example.com:8443/myapp`, and `logoutPath` must be prefixed with`/myapp`, otherwise the OIDC authentication
-will fail because the redirect and logout requests will not match the target HTTPRoute and therefore can't be processed
+HTTPRoute is configured to match the host `www.example.com` and the path `/myapp`, so the `redirectURL` must be prefixed
+with `https://www.example.com:8443/myapp`, and `logoutPath` must be prefixed with`/myapp`, otherwise the OIDC authentication
+will fail because the redirect and logout requests will not match the target HTTPRoute and therefore can't be processed
by the OAuth2 filter on that HTTPRoute.
Note: please replace the ${CLIENT_ID} in the below yaml snippet with the actual Client ID that you got from the OIDC provider.
@@ -135,10 +134,10 @@ kind: SecurityPolicy
metadata:
name: oidc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
oidc:
provider:
issuer: "https://accounts.google.com"
@@ -161,10 +160,10 @@ kind: SecurityPolicy
metadata:
name: oidc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
oidc:
provider:
issuer: "https://accounts.google.com"
@@ -201,8 +200,8 @@ Put www.example.com in the /etc/hosts file in your test machine, so we can use t
127.0.0.1 www.example.com
```
-Open a browser and navigate to the `https://www.example.com:8443/myapp` address. You should be redirected to the Google
-login page. After you successfully login, you should see the response from the backend service.
+Open a browser and navigate to the `https://www.example.com:8443/myapp` address. You should be redirected to the Google
+login page. After you successfully login, you should see the response from the backend service.
Clean the cookies in the browser and try to access `https://www.example.com:8443/foo` address. You should be able to see
this page since the path `/foo` is not protected by the OIDC policy.
@@ -222,12 +221,80 @@ If you haven't registered an OIDC application, follow the steps in the previous
If you haven't created a kubernetes secret, follow the steps in the previous section to create a kubernetes secret.
+### Create an HTTPRoute with a different subdomain
+
+Let's create another HTTPRoute in the same Gateway, but with a different subdomain.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the HTTPRoute status:
+
+```shell
+kubectl get httproute/foo -o yaml
+```
+
### Create a SecurityPolicy
-Create or update the SecurityPolicy to target the Gateway instead of the HTTPRoute. **Please notice that the `redirectURL`
-and `logoutPath` must match one of the HTTPRoutes associated with the Gateway.** In this example, the target Gateway has
-two HTTPRoutes associated with it, one with the host `www.example.com` and the path `/myapp`, and the other with the host
-`www.example.com` and the path `/`. Either one of the HTTPRoutes can be used to match the `redirectURL` and `logoutPath`.
+Create or update the SecurityPolicy to target the Gateway instead of the HTTPRoute. **Please notice that the `redirectURL`
+and `logoutPath` must match one of the HTTPRoutes associated with the Gateway.** In this example, the target Gateway has
+three HTTPRoutes associated with it, one with the host `www.example.com` and the path `/myapp`, one with the host
+`www.example.com` and the path `/`, and one with the host `foo.example.com` and the path `/`. Any of these HTTPRoutes
+can be used to match the `redirectURL` and `logoutPath`.
+
+By default, the access token and ID token cookies are set to the host of the request, excluding subdomains. To allow the
+token cookies to be shared across subdomains and prevent users from having to log in again when switching between subdomains,
+the `cookieDomain` field needs to be set to the root domain. In this example, the root domain is `example.com`.
+
+Note: if a `cookieDomain` is added to an existing SecurityPolicy, the cookies in the browser must be cleared before sending a new request to the Gateway, otherwise the cookies with the old subdomain will take precedence and be sent to the Gateway, causing the OIDC authentication to fail.
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -239,10 +306,10 @@ kind: SecurityPolicy
metadata:
name: oidc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
oidc:
provider:
issuer: "https://accounts.google.com"
@@ -251,6 +318,7 @@ spec:
name: "my-app-client-secret"
redirectURL: "https://www.example.com:8443/myapp/oauth2/callback"
logoutPath: "/myapp/logout"
+ cookieDomain: "example.com"
EOF
```
@@ -265,10 +333,10 @@ kind: SecurityPolicy
metadata:
name: oidc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
oidc:
provider:
issuer: "https://accounts.google.com"
@@ -277,6 +345,7 @@ spec:
name: "my-app-client-secret"
redirectURL: "https://www.example.com:8443/myapp/oauth2/callback"
logoutPath: "/myapp/logout"
+ cookieDomain: "example.com"
```
{{% /tab %}}
@@ -288,16 +357,187 @@ Verify the SecurityPolicy configuration:
kubectl get securitypolicy/oidc-example -o yaml
```
+### Update the Listener TLS certificate to support multiple subdomains
+
+Create a multi-domain wildcard certificate for `*.example.com`.
+
+```shell
+openssl req -out wildcard.csr -newkey rsa:2048 -nodes -keyout wildcard.key -subj "/CN=*.example.com/O=example organization"
+openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in wildcard.csr -out wildcard.crt
+```
+
+Replace the TLS certificate of the Gateway with the wildcard certificate.
+
+```shell
+kubectl delete secret example-cert
+kubectl create secret tls example-cert --key=wildcard.key --cert=wildcard.crt
+```
+
### Testing
If you haven't done so, follow the steps in the previous section to port forward gateway port to localhost and put
www.example.com in the /etc/hosts file in your test machine.
-Open a browser and navigate to the `https://www.example.com:8443/foo` address. You should be redirected to the Google
+Also, put foo.example.com in the /etc/hosts file in your test machine.
+
+```shell
+...
+127.0.0.1 foo.example.com
+```
+
+Open a browser and navigate to the `https://www.example.com:8443/myapp` address. You should be redirected to the Google
login page. After you successfully login, you should see the response from the backend service.
-You can also try to access `https://www.example.com:8443/myapp` address. You should be able to see this page since the
-path `/myapp` is protected by the same OIDC policy.
+You can also try to access `https://foo.example.com:8443` and `https://www.example.com:8443/bar` addresses. You should
+be able to see the response from the backend service since these HTTPRoutes are also protected by the same OIDC config,
+and the cookies are shared across subdomains.
+
+## Connect to an OIDC Provider with Self-Signed Certificate
+
+In some scenarios, the OIDC provider may use a self-signed certificate. To connect to an OIDC provider with a self-signed certificate, you need to configure it using the [Backend] resource within the [SecurityPolicy]. Additionally, use the [BackendTLSPolicy] to specify the CA certificate required to authenticate the OIDC provider.
+
+The following example demonstrates how to configure the OIDC provider with a self-signed certificate.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+For more information about [Backend] and [BackendTLSPolicy], refer to the [Backend Routing][backend-routing] and [Backend TLS: Gateway to Backend][backend-tls] tasks.
## Clean-Up
@@ -309,6 +549,7 @@ Delete the SecurityPolicy, the secret and the HTTPRoute:
kubectl delete securitypolicy/oidc-example
kubectl delete secret/my-app-client-secret
kubectl delete httproute/myapp
+kubectl delete httproute/foo
```
## Next Steps
@@ -317,6 +558,10 @@ Checkout the [Developer Guide](../../../../contributions/develop) to get involve
[oidc]: https://openid.net/connect/
[google-oidc]: https://developers.google.com/identity/protocols/oauth2/openid-connect
-[SecurityPolicy]: ../../../../contributions/design/security-policy
+[SecurityPolicy]: ../../../api/extension_types#securitypolicy
[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[Backend]: ../../../api/extension_types#backend
+[BackendTLSPolicy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
+[backend-routing]: ../traffic/backend
+[backend-tls]: ../backend-tls
diff --git a/site/content/en/docs/tasks/security/private-key-provider.md b/site/content/en/docs/tasks/security/private-key-provider.md
index cf40a96e9e1..24544f67973 100644
--- a/site/content/en/docs/tasks/security/private-key-provider.md
+++ b/site/content/en/docs/tasks/security/private-key-provider.md
@@ -14,7 +14,9 @@ This task will walk you through the steps required to configure TLS Termination
## Prerequisites
-### For QAT
+{{< tabpane text=true >}}
+
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
- Install Linux kernel 5.17 or similar
- Ensure the node has QAT devices by checking the QAT physical function devices presented. [Supported Devices](https://intel.github.io/quickassist/qatlib/requirements.html#qat2-0-qatlib-supported-devices)
@@ -88,7 +90,9 @@ This task will walk you through the steps required to configure TLS Termination
kubectl get node -o yaml| grep qat.intel.com
```
-### For CryptoMB:
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
It required the node with 3rd generation Intel Xeon Scalable processor server processors, or later.
- For kubernetes Cluster, if not all nodes that support Intel® AVX-512 in Kubernetes cluster, you need to add some labels to divide these two kinds of nodes manually or using [NFD](https://github.com/kubernetes-sigs/node-feature-discovery).
@@ -110,6 +114,10 @@ It required the node with 3rd generation Intel Xeon Scalable processor server pr
cat /proc/cpuinfo |grep avx512f|grep avx512dq|grep avx512bw|grep avx512_vbmi2|grep avx512ifma
```
+{{% /tab %}}
+
+{{< /tabpane >}}
+
## Installation
* Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway.
@@ -161,11 +169,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-* After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in
-
- ```shell
- kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
- ```
+{{< boilerplate rollout-envoy-gateway >}}
## Create gateway for TLS termination
@@ -214,10 +218,14 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
-### Change EnvoyProxy configuration for QAT
+## Change EnvoyProxy configuration
Using the envoyproxy image with contrib extensions and add qat resources requesting, ensure the k8s scheduler find out a machine with required resource.
+{{< tabpane text=true >}}
+
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
+
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -285,7 +293,9 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
-### Change EnvoyProxy configuration for CryptoMB
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
Using the envoyproxy image with contrib extensions and add the node affinity to scheduling the Envoy Gateway pod on the machine with required CPU instructions.
@@ -386,9 +396,11 @@ spec:
Or using `preferredDuringSchedulingIgnoredDuringExecution` for best effort scheduling, or not doing any node affinity, just doing the random scheduling. The CryptoMB private key provider supports software fallback if the required CPU instructions aren't here.
-## Apply EnvoyPatchPolicy to enable private key provider
+{{% /tab %}}
+
+{{< /tabpane >}}
-### Benchmark before enabling private key provider
+## Benchmark before enabling private key provider
First follow the instructions in [TLS Termination for TCP](./tls-termination) to do the functionality test.
@@ -416,7 +428,11 @@ Benchmark the gateway with fortio.
fortio load -c 10 -k -qps 0 -t 30s -keepalive=false https://www.example.com:${NODE_PORT}
```
-### For QAT
+## Apply EnvoyPatchPolicy to enable private key provider
+
+{{< tabpane text=true >}}
+
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -433,7 +449,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
@@ -475,7 +490,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
@@ -503,7 +517,9 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
-### For CryptoMB
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -520,7 +536,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
@@ -562,7 +577,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
@@ -590,7 +604,11 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
-### Benchmark after enabling private key provider
+{{% /tab %}}
+
+{{< /tabpane >}}
+
+## Benchmark after enabling private key provider
First follow the instructions in [TLS Termination for TCP](./tls-termination) to do the functionality test again.
@@ -600,6 +618,8 @@ Benchmark the gateway with fortio.
fortio load -c 64 -k -qps 0 -t 30s -keepalive=false https://www.example.com:${NODE_PORT}
```
+## Benchmark Result
+
You will see a performance boost after private key provider enabled. For example, you will get results as below.
Without private key provider:
@@ -608,14 +628,26 @@ Without private key provider:
All done 43069 calls (plus 10 warmup) 6.966 ms avg, 1435.4 qps
```
-With CryptoMB private key provider, the QPS is over 2 times than without private key provider.
+{{< tabpane text=true >}}
-```shell
-All done 93983 calls (plus 128 warmup) 40.880 ms avg, 3130.5 qps
-```
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
With QAT private key provider, the QPS is over 3 times than without private key provider
```shell
All done 134746 calls (plus 128 warmup) 28.505 ms avg, 4489.6 qps
```
+
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
+
+With CryptoMB private key provider, the QPS is over 2 times than without private key provider.
+
+```shell
+All done 93983 calls (plus 128 warmup) 40.880 ms avg, 3130.5 qps
+```
+
+{{% /tab %}}
+
+{{< /tabpane >}}
diff --git a/site/content/en/docs/tasks/security/restrict-ip-access.md b/site/content/en/docs/tasks/security/restrict-ip-access.md
index ba6af118252..ab8965d7966 100644
--- a/site/content/en/docs/tasks/security/restrict-ip-access.md
+++ b/site/content/en/docs/tasks/security/restrict-ip-access.md
@@ -10,8 +10,7 @@ This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HT
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Configuration
@@ -33,8 +32,8 @@ kind: SecurityPolicy
metadata:
name: authorization-client-ip
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
authorization:
@@ -58,17 +57,17 @@ kind: SecurityPolicy
metadata:
name: authorization-client-ip
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
authorization:
defaultAction: Deny
rules:
- - action: Allow
- principal:
- clientCIDRs:
- - 10.0.1.0/24
+ - action: Allow
+ principal:
+ clientCIDRs:
+ - 10.0.1.0/24
```
{{% /tab %}}
@@ -102,10 +101,10 @@ spec:
clientIPDetection:
xForwardedFor:
numTrustedHops: 1
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
EOF
```
@@ -123,10 +122,10 @@ spec:
clientIPDetection:
xForwardedFor:
numTrustedHops: 1
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
```
{{% /tab %}}
diff --git a/site/content/en/docs/tasks/security/secure-gateways.md b/site/content/en/docs/tasks/security/secure-gateways.md
index af5e922412d..2c8d5043812 100644
--- a/site/content/en/docs/tasks/security/secure-gateways.md
+++ b/site/content/en/docs/tasks/security/secure-gateways.md
@@ -11,8 +11,7 @@ This task uses a self-signed CA, so it should be used for testing and demonstrat
## Installation
-Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## TLS Certificates
@@ -513,8 +512,88 @@ Since the multiple certificates are configured on the same Gateway listener, Env
{{% /tab %}}
{{< /tabpane >}}
+## Customize Gateway TLS Parameters
+
+In addition to enablement of TLS with Gateway-API, Envoy Gateway supports customizing TLS parameters.
+To achieve this, the [ClientTrafficPolicy][] resource can be used to specify TLS parameters.
+We will customize the minimum supported TLS version in this example to TLSv1.3.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+## Testing TLS Parameters
+
+Attempt to connecting using an unsupported TLS version:
+
+```shell
+curl -v -HHost:www.sample.com --resolve "www.sample.com:8443:127.0.0.1" \
+--cacert sample.com.crt --tlsv1.2 --tls-max 1.2 https://www.sample.com:8443/get -I
+
+[...]
+
+* ALPN: curl offers h2,http/1.1
+* (304) (OUT), TLS handshake, Client hello (1):
+* LibreSSL/3.3.6: error:1404B42E:SSL routines:ST_CONNECT:tlsv1 alert protocol version
+* Closing connection
+curl: (35) LibreSSL/3.3.6: error:1404B42E:SSL routines:ST_CONNECT:tlsv1 alert protocol version
+```
+
+The output shows that the connection fails due to an unsupported TLS protocol version used by the client. Now, connect
+to the Gateway without specifying a client version, and note that the connection is established with TLSv1.3.
+
+```shell
+curl -v -HHost:www.sample.com --resolve "www.sample.com:8443:127.0.0.1" \
+--cacert sample.com.crt https://www.sample.com:8443/get -I
+
+[...]
+
+* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
+```
+
## Next Steps
Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
[ReferenceGrant]: https://gateway-api.sigs.k8s.io/api-types/referencegrant/
+[ClientTrafficPolicy]: ../../api/extension_types#clienttrafficpolicy
\ No newline at end of file
diff --git a/site/content/en/docs/tasks/security/tls-cert-manager.md b/site/content/en/docs/tasks/security/tls-cert-manager.md
index d51fa469e8c..61ebb5c0162 100644
--- a/site/content/en/docs/tasks/security/tls-cert-manager.md
+++ b/site/content/en/docs/tasks/security/tls-cert-manager.md
@@ -18,8 +18,7 @@ Changing to the Let's Encrypt production environment is straight-forward after t
## Installation
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Deploying cert-manager
@@ -76,7 +75,7 @@ EOF
We now have to patch the example Gateway to reference cert-manager:
```console
-$ kubectl patch gateway/eg --patch-file - <}}
## TLS Certificates
diff --git a/site/content/en/docs/tasks/security/tls-termination.md b/site/content/en/docs/tasks/security/tls-termination.md
index e4534dd57e1..1100b04699f 100644
--- a/site/content/en/docs/tasks/security/tls-termination.md
+++ b/site/content/en/docs/tasks/security/tls-termination.md
@@ -11,9 +11,10 @@ This task uses a self-signed CA, so it should be used for testing and demonstrat
## Installation
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway.
+{{< boilerplate prerequisites >}}
## TLS Certificates
+
Generate the certificates and keys used by the Gateway to terminate client TLS connections.
Create a root certificate and private key to sign certificates:
diff --git a/site/content/en/docs/tasks/traffic/backend.md b/site/content/en/docs/tasks/traffic/backend.md
index 02de7161fe2..55d125a27ad 100644
--- a/site/content/en/docs/tasks/traffic/backend.md
+++ b/site/content/en/docs/tasks/traffic/backend.md
@@ -7,26 +7,28 @@ Envoy Gateway supports routing to native K8s resources such as `Service` and `Se
## Motivation
The Backend API was added to support several use cases:
- Allowing users to integrate Envoy with services (Ext Auth, Rate Limit, ALS, ...) using Unix Domain Sockets, which are currently not supported by K8s.
-- Simplify [routing to cluster-external backends][], which currently requires users to maintain both K8s `Service` and `EndpointSlice` resources.
+- Simplify [routing to cluster-external backends][], which currently requires users to maintain both K8s `Service` and `EndpointSlice` resources.
## Warning
-Similar to the K8s EndpointSlice API, the Backend API can be misused to allow traffic to be sent to otherwise restricted destinations, as described in [CVE-2021-25740][].
+Similar to the K8s EndpointSlice API, the Backend API can be misused to allow traffic to be sent to otherwise restricted destinations, as described in [CVE-2021-25740][].
A Backend resource can be used to:
- Expose a Service or Pod that should not be accessible
- Reference a Service or Pod by a Route without appropriate Reference Grants
- Expose the Envoy Proxy localhost (including the Envoy admin endpoint)
-For these reasons, the Backend API is disabled by default in Envoy Gateway configuration. Envoy Gateway admins are advised to follow [upstream recommendations][] and restrict access to the Backend API using K8s RBAC.
+For these reasons, the Backend API is disabled by default in Envoy Gateway configuration. Envoy Gateway admins are advised to follow [upstream recommendations][] and restrict access to the Backend API using K8s RBAC.
## Restrictions
The Backend API is currently supported only in the following BackendReferences:
- [HTTPRoute]: IP and FQDN endpoints
+- [TLSRoute]: IP and FQDN endpoints
- [Envoy Extension Policy] (ExtProc): IP, FQDN and unix domain socket endpoints
+- [Security Policy]: IP and FQDN endpoints for the OIDC providers
The Backend API supports attachment the following policies:
-- [Backend TLS Policy][]
+- [Backend TLS Policy][]
Certain restrictions apply on the value of hostnames and addresses. For example, the loopback IP address range and the localhost hostname are forbidden.
@@ -36,8 +38,7 @@ Envoy Gateway does not manage the lifecycle of unix domain sockets referenced by
### Prerequisites
-* Follow the steps from the [Quickstart](../../quickstart) task to install Envoy Gateway and the example manifest.
- Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
### Enable Backend
@@ -95,11 +96,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-* After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
## Testing
@@ -205,7 +202,9 @@ curl -I -HHost:www.example.com http://${GATEWAY_HOST}/headers
[CVE-2021-25740]: https://nvd.nist.gov/vuln/detail/CVE-2021-25740
[upstream recommendations]: https://github.com/kubernetes/kubernetes/issues/103675
[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[TLSRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute
[Envoy Extension Policy]: ../../../api/extension_types#envoyextensionpolicy
+[Security Policy]: ../../../api/extension_types#oidcprovider
[Backend TLS Policy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
[EnvoyProxy]: ../../../api/extension_types#envoyproxy
[EnvoyGateway]: ../../../api/extension_types#envoygateway
diff --git a/site/content/en/docs/tasks/traffic/circuit-breaker.md b/site/content/en/docs/tasks/traffic/circuit-breaker.md
index d3631739549..6a359c5e0dc 100644
--- a/site/content/en/docs/tasks/traffic/circuit-breaker.md
+++ b/site/content/en/docs/tasks/traffic/circuit-breaker.md
@@ -20,9 +20,10 @@ This instantiated resource can be linked to a [Gateway][], [HTTPRoute][] or [GRP
### Install Envoy Gateway
-* Follow the installation step from the [Quickstart](../../quickstart) to install Envoy Gateway and sample resources.
+{{< boilerplate prerequisites >}}
### Install the hey load testing tool
+
* The `hey` CLI will be used to generate load and measure response times. Follow the installation instruction from the [Hey project] docs.
## Test and customize circuit breaker settings
@@ -72,10 +73,10 @@ kind: BackendTrafficPolicy
metadata:
name: circuitbreaker-for-route
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
circuitBreaker:
maxPendingRequests: 0
maxParallelRequests: 10
@@ -93,10 +94,10 @@ kind: BackendTrafficPolicy
metadata:
name: circuitbreaker-for-route
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
circuitBreaker:
maxPendingRequests: 0
maxParallelRequests: 10
diff --git a/site/content/en/docs/tasks/traffic/client-traffic-policy.md b/site/content/en/docs/tasks/traffic/client-traffic-policy.md
index 894770116ab..2099ea13685 100644
--- a/site/content/en/docs/tasks/traffic/client-traffic-policy.md
+++ b/site/content/en/docs/tasks/traffic/client-traffic-policy.md
@@ -4,7 +4,6 @@ title: "Client Traffic Policy"
This task explains the usage of the [ClientTrafficPolicy][] API.
-
## Introduction
The [ClientTrafficPolicy][] API allows system administrators to configure
@@ -18,8 +17,7 @@ This API was added as a new policy attachment resource that can be applied to Ga
### Prerequisites
-* Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
### Support TCP keepalive for downstream client
@@ -35,9 +33,9 @@ metadata:
namespace: default
spec:
targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
tcpKeepalive:
idleTime: 20m
interval: 60s
@@ -57,10 +55,10 @@ metadata:
name: enable-tcp-keepalive-policy
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
tcpKeepalive:
idleTime: 20m
interval: 60s
@@ -214,10 +212,10 @@ metadata:
name: enable-proxy-protocol-policy
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
enableProxyProtocol: true
EOF
```
@@ -234,10 +232,10 @@ metadata:
name: enable-proxy-protocol-policy
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
enableProxyProtocol: true
```
@@ -352,9 +350,9 @@ metadata:
namespace: default
spec:
targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
clientIPDetection:
xForwardedFor:
numTrustedHops: 2
@@ -373,10 +371,10 @@ metadata:
name: http-client-ip-detection
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
clientIPDetection:
xForwardedFor:
numTrustedHops: 2
@@ -502,10 +500,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
timeout:
http:
requestReceivedTimeout: 2s
@@ -523,10 +521,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
timeout:
http:
requestReceivedTimeout: 2s
@@ -582,10 +580,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
timeout:
http:
idleTimeout: 5s
@@ -603,10 +601,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
timeout:
http:
idleTimeout: 5s
@@ -647,10 +645,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
connection:
bufferLimit: 1024
EOF
@@ -667,10 +665,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
connection:
bufferLimit: 1024
```
diff --git a/site/content/en/docs/tasks/traffic/connection-limit.md b/site/content/en/docs/tasks/traffic/connection-limit.md
index 55b0e005f8a..9c0e9bbc1fc 100644
--- a/site/content/en/docs/tasks/traffic/connection-limit.md
+++ b/site/content/en/docs/tasks/traffic/connection-limit.md
@@ -25,10 +25,10 @@ When a [Client Traffic Policy][] is attached to a gateway, the connection limit
### Install Envoy Gateway
-* Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the HTTPRoute example manifest.
- Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
### Install the hey load testing tool
+
* The `hey` CLI will be used to generate load and measure response times. Follow the installation instruction from the [Hey project] docs.
## Test and customize connection limit settings
@@ -68,10 +68,10 @@ metadata:
name: connection-limit-ctp
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
connection:
connectionLimit:
value: 5
@@ -90,10 +90,10 @@ metadata:
name: connection-limit-ctp
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
connection:
connectionLimit:
value: 5
diff --git a/site/content/en/docs/tasks/traffic/direct-response.md b/site/content/en/docs/tasks/traffic/direct-response.md
new file mode 100644
index 00000000000..dfaa6755d4d
--- /dev/null
+++ b/site/content/en/docs/tasks/traffic/direct-response.md
@@ -0,0 +1,203 @@
+---
+title: "Direct Response"
+---
+
+Direct responses are valuable in cases where you want the gateway itself
+to handle certain requests without forwarding them to backend services.
+This task shows you how to configure them.
+
+## Installation
+
+Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+## Testing Direct Response
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/inline
+```
+
+```console
+* Trying 127.0.0.1:80...
+* Connected to 127.0.0.1 (127.0.0.1) port 80
+> GET /inline HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.4.0
+> Accept: */*
+>
+< HTTP/1.1 503 Service Unavailable
+< content-type: text/plain
+< content-length: 32
+< date: Sat, 02 Nov 2024 00:35:48 GMT
+<
+* Connection #0 to host 127.0.0.1 left intact
+Oops! Your request is not found.
+```
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/value-ref
+```
+
+```console
+* Trying 127.0.0.1:80...
+* Connected to 127.0.0.1 (127.0.0.1) port 80
+> GET /value-ref HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.4.0
+> Accept: */*
+>
+< HTTP/1.1 500 Internal Server Error
+< content-type: application/json
+< content-length: 34
+< date: Sat, 02 Nov 2024 00:35:55 GMT
+<
+* Connection #0 to host 127.0.0.1 left intact
+{"error": "Internal Server Error"}
+```
diff --git a/site/content/en/docs/tasks/traffic/failover.md b/site/content/en/docs/tasks/traffic/failover.md
new file mode 100644
index 00000000000..625d5e2afcd
--- /dev/null
+++ b/site/content/en/docs/tasks/traffic/failover.md
@@ -0,0 +1,566 @@
+---
+title: Failover
+---
+
+Active-passive failover in an API gateway setup is like having a backup plan in place to keep things
+running smoothly if something goes wrong. Here’s why it’s valuable:
+
+* Staying Online: When the main (or "active") backend has issues or goes offline,
+the fallback (or "passive") backend is ready to step in instantly.
+This helps keep your API accessible and your services running, so users don’t even notice any interruptions.
+
+* Automatic Switch Over: If a problem occurs, the system can automatically switch traffic over to the fallback backend.
+This avoids needing someone to jump in and fix things manually, which could take time and might even lead to mistakes.
+
+* Lower Costs: In an active-passive setup, the fallback backend doesn’t need to work all the time—it’s just on standby.
+This can save on costs (like cloud egress costs) compared to setups where both backend are running at full capacity.
+
+* Peace of Mind with Redundancy: Although the fallback backend isn’t handling traffic daily, it's there as a safety net.
+If something happens with the primary backend, the backup can take over immediately, ensuring your service doesn’t skip a beat.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## Test
+
+* We'll first create two services & deployments, called `active` and `passive`, representing an `active` and `passive` backend application.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+* Follow the instructions [here](./../../tasks/traffic/backend/#enable-backend) to enable the Backend API
+
+* Create two Backend resources that are used to represent the `active` backend and `passive` backend.
+Note, we've set `fallback: true` for the `passive` backend to indicate its a passive backend
+
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+* Lets create an HTTPRoute that can route to both these backends
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+* Lets configure a `BackendTrafficPolicy` with a passive health check setting to detect an transient errors.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+
+* Lets send 10 requests. You should see that they all go to the `active` backend.
+
+```shell
+for i in {1..10; do curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/test 2>/dev/null | jq .pod; done
+```
+
+```console
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+```
+
+* Lets simulate a failure in the `active` backend by changing the server listening port to `5000`
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+* Lets send 10 requests again. You should see them all being sent to the `passive` backend
+
+```shell
+for i in {1..10; do curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/test 2>/dev/null | jq .pod; done
+```
+
+```console
+parse error: Invalid numeric literal at line 1, column 9
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+```
+
+The first error can be avoided by configuring [retries](./../../tasks/traffic/retry.md).
diff --git a/site/content/en/docs/tasks/traffic/fault-injection.md b/site/content/en/docs/tasks/traffic/fault-injection.md
index d4f536dbb33..82068c4cf55 100644
--- a/site/content/en/docs/tasks/traffic/fault-injection.md
+++ b/site/content/en/docs/tasks/traffic/fault-injection.md
@@ -13,11 +13,12 @@ This instantiated resource can be linked to a [Gateway][], [HTTPRoute][] or [GRP
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
+{{< boilerplate prerequisites >}}
+
For GRPC - follow the steps from the [GRPC Routing](../grpc-routing) example.
-Before proceeding, you should be able to query the example backend using HTTP or GRPC.
### Install the hey load testing tool
+
* The `hey` CLI will be used to generate load and measure response times. Follow the installation instruction from the [Hey project] docs.
## Configuration
@@ -36,8 +37,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-50-percent-abort
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: foo
faultInjection:
@@ -50,8 +51,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-delay
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: bar
faultInjection:
@@ -113,8 +114,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-50-percent-abort
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: foo
faultInjection:
@@ -127,8 +128,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-delay
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: bar
faultInjection:
@@ -210,8 +211,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-abort
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: GRPCRoute
name: yages
faultInjection:
@@ -250,8 +251,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-abort
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: GRPCRoute
name: yages
faultInjection:
diff --git a/site/content/en/docs/tasks/traffic/gateway-address.md b/site/content/en/docs/tasks/traffic/gateway-address.md
index bd87726c139..f49d7f99e01 100644
--- a/site/content/en/docs/tasks/traffic/gateway-address.md
+++ b/site/content/en/docs/tasks/traffic/gateway-address.md
@@ -10,7 +10,7 @@ Depending on the Service Type, the addresses of gateway can be used as:
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
+{{< boilerplate prerequisites >}}
## External IPs
diff --git a/site/content/en/docs/tasks/traffic/global-rate-limit.md b/site/content/en/docs/tasks/traffic/global-rate-limit.md
index 83c61861247..47eac33bc3e 100644
--- a/site/content/en/docs/tasks/traffic/global-rate-limit.md
+++ b/site/content/en/docs/tasks/traffic/global-rate-limit.md
@@ -27,8 +27,7 @@ has its own 100r/s rate limit bucket.
### Install Envoy Gateway
-* Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the HTTPRoute example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
### Install Redis
@@ -215,11 +214,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-* After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
## Rate Limit Specific User
@@ -236,8 +231,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -265,8 +260,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -438,11 +433,11 @@ server: envoy
```
-## Rate Limit Distinct Users
+## Rate Limit Distinct Users Except Admin
Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differentiated based on the
value in the `x-user-id` header. Here, user `one` (recognised from the traffic flow using the header `x-user-id` and value `one`) will be rate limited at 3 requests/hour
-and so will user `two` (recognised from the traffic flow using the header `x-user-id` and value `two`).
+and so will user `two` (recognised from the traffic flow using the header `x-user-id` and value `two`). But if `x-user-id` is `admin`, it will not be rate limited even beyond 3 requests/hour.
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -454,8 +449,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -466,6 +461,9 @@ spec:
- headers:
- type: Distinct
name: x-user-id
+ - name: x-user-id
+ value: admin
+ invert: true
limit:
requests: 3
unit: Hour
@@ -483,8 +481,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -641,6 +639,47 @@ transfer-encoding: chunked
```
+But when the value for header `x-user-id` is set to `admin` and 4 requests are sent, all 4 of them should respond with 200 OK.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: admin" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+```
+
## Rate Limit All Requests
This example shows you how to rate limit all requests matching the HTTPRoute rule at 3 requests/Hour by leaving the `clientSelectors` field unset.
@@ -655,8 +694,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -680,8 +719,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -811,8 +850,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -860,8 +899,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -871,7 +910,7 @@ spec:
- clientSelectors:
- sourceCIDR:
value: 0.0.0.0/0
- type: distinct
+ type: Distinct
limit:
requests: 3
unit: Hour
@@ -951,8 +990,8 @@ kind: SecurityPolicy
metadata:
name: jwt-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: example
jwt:
@@ -969,8 +1008,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: example
rateLimit:
@@ -1019,8 +1058,8 @@ kind: SecurityPolicy
metadata:
name: jwt-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: example
jwt:
@@ -1037,8 +1076,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: example
rateLimit:
@@ -1081,11 +1120,11 @@ spec:
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
```shell
-TOKEN1=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/with-different-claim.jwt -s) && echo "$TOKEN1" | cut -d '.' -f2 - | base64 --decode -
+TOKEN1=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/with-different-claim.jwt -s) && echo "$TOKEN1" | cut -d '.' -f2 - | base64 --decode
```
### Rate limit by carrying `TOKEN`
@@ -1288,11 +1327,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-* After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
[Global Rate Limiting]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/global_rate_limiting
[Local rate limiting]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/local_rate_limiting
diff --git a/site/content/en/docs/tasks/traffic/grpc-routing.md b/site/content/en/docs/tasks/traffic/grpc-routing.md
index 7c41b54c885..15f10601bc2 100644
--- a/site/content/en/docs/tasks/traffic/grpc-routing.md
+++ b/site/content/en/docs/tasks/traffic/grpc-routing.md
@@ -7,8 +7,7 @@ To learn more about gRPC routing, refer to the [Gateway API documentation][].
## Prerequisites
-Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Installation
diff --git a/site/content/en/docs/tasks/traffic/http-redirect.md b/site/content/en/docs/tasks/traffic/http-redirect.md
index b3177e89263..49ccd59ee77 100644
--- a/site/content/en/docs/tasks/traffic/http-redirect.md
+++ b/site/content/en/docs/tasks/traffic/http-redirect.md
@@ -9,8 +9,7 @@ learn more about HTTP routing, refer to the [Gateway API documentation][].
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTPS.
+{{< boilerplate prerequisites >}}
## Redirects
diff --git a/site/content/en/docs/tasks/traffic/http-request-headers.md b/site/content/en/docs/tasks/traffic/http-request-headers.md
index 7bc709c49c6..5b73bfaf8d3 100644
--- a/site/content/en/docs/tasks/traffic/http-request-headers.md
+++ b/site/content/en/docs/tasks/traffic/http-request-headers.md
@@ -14,8 +14,7 @@ client.
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Adding Request Headers
@@ -443,7 +442,179 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
+## Early Header Modification
+
+In some cases, it could be necessary to modify headers before the proxy performs any sort of processing, routing or tracing. Envoy Gateway supports this functionality using the [ClientTrafficPolicy][] API.
+
+A ClientTrafficPolicy resource can be attached to a Gateway resource to configure early header modifications for all its routes. In the following example we will demonstrate how early header modification can be configured.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+Querying `headers.example/get` should result in a `200` response from the example Gateway and the output from the
+example app should indicate that the upstream example app received the following headers:
+- `early-added-header` contains early (ClientTrafficPolicy) and late (RouteFilter) values
+- `early-set-header` contains only early (ClientTrafficPolicy) and late (RouteFilter) values, since the early modification overwritten the client value.
+- `early-removed-header` contains only the late (RouteFilter) value, since the early modification deleted the client value.
+
+```console
+$ curl -vvv --header "Host: headers.example" "http://${GATEWAY_HOST}/get" --header "early-added-header: client" --header "early-set-header: client" --header "early-removed-header: client"
+...
+> GET /get HTTP/1.1
+> Host: headers.example
+> User-Agent: curl/7.81.0
+> Accept: */*
+> add-header: something
+>
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< content-length: 474
+< x-envoy-upstream-service-time: 0
+< server: envoy
+<
+
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "Early-Added-Header": [
+ "client",
+ "early",
+ "late"
+ ],
+ "Early-Set-Header": [
+ "early",
+ "late"
+ ],
+ "Early-removed-Header": [
+ "late"
+ ]
+...
+```
+
[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/
[HTTPRoute filters]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter
[Gateway API documentation]: https://gateway-api.sigs.k8s.io/
[req_filter]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPHeaderFilter
+[ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy
diff --git a/site/content/en/docs/tasks/traffic/http-request-mirroring.md b/site/content/en/docs/tasks/traffic/http-request-mirroring.md
index f22ef51da36..5c1c8065652 100644
--- a/site/content/en/docs/tasks/traffic/http-request-mirroring.md
+++ b/site/content/en/docs/tasks/traffic/http-request-mirroring.md
@@ -6,10 +6,9 @@ The [HTTPRoute][] resource allows one or more [backendRefs][] to be provided. Re
When requests are made to a `HTTPRoute` that uses a `HTTPRequestMirrorFilter`, the response will never come from the `backendRef` defined in the filter. Responses from the mirror `backendRef` are always ignored.
-## Installation
+## Prerequisites
-Follow the steps from the [Quickstart][] to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Mirroring the Traffic
@@ -440,7 +439,6 @@ spec:
Error from server: error when creating "STDIN": admission webhook "validate.gateway.networking.k8s.io" denied the request: spec.rules[0].filters: Invalid value: "RequestMirror": cannot be used multiple times in the same rule
```
-[Quickstart]: ../../quickstart/
[Traffic Splitting]: ../http-traffic-splitting/
[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/
[backendRefs]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.BackendRef
diff --git a/site/content/en/docs/tasks/traffic/http-response-headers.md b/site/content/en/docs/tasks/traffic/http-response-headers.md
index 60121674b00..b1588e87a89 100644
--- a/site/content/en/docs/tasks/traffic/http-response-headers.md
+++ b/site/content/en/docs/tasks/traffic/http-response-headers.md
@@ -12,8 +12,7 @@ upstream service.
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Adding Response Headers
diff --git a/site/content/en/docs/tasks/traffic/http-routing.md b/site/content/en/docs/tasks/traffic/http-routing.md
index aba57adc9b2..bb9eba88157 100644
--- a/site/content/en/docs/tasks/traffic/http-routing.md
+++ b/site/content/en/docs/tasks/traffic/http-routing.md
@@ -9,8 +9,7 @@ Services. To learn more about HTTP routing, refer to the [Gateway API documentat
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Installation
@@ -141,10 +140,10 @@ kind: SecurityPolicy
metadata:
name: jwt-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: jwt-claim-routing
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: jwt-claim-routing
jwt:
providers:
- name: example
@@ -209,10 +208,10 @@ kind: SecurityPolicy
metadata:
name: jwt-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: jwt-claim-routing
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: jwt-claim-routing
jwt:
providers:
- name: example
@@ -271,7 +270,7 @@ spec:
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
Test routing to the `foo-svc` backend by specifying a JWT Token with a claim `name: John Doe`.
@@ -284,7 +283,7 @@ curl -sS -H "Host: foo.example.com" -H "Authorization: Bearer $TOKEN" "http://${
Get another JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/with-different-claim.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/with-different-claim.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
Test HTTP routing to the `bar-svc` backend by specifying a JWT Token with a claim `name: Tom`.
diff --git a/site/content/en/docs/tasks/traffic/http-timeouts.md b/site/content/en/docs/tasks/traffic/http-timeouts.md
index 1eb9beabb24..4fb264204ed 100644
--- a/site/content/en/docs/tasks/traffic/http-timeouts.md
+++ b/site/content/en/docs/tasks/traffic/http-timeouts.md
@@ -12,10 +12,9 @@ The [HTTPRouteTimeouts][] supports two kinds of timeouts:
__Note:__ The Request duration must be >= BackendRequest duration
-## Installation
+## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Verification
diff --git a/site/content/en/docs/tasks/traffic/http-traffic-splitting.md b/site/content/en/docs/tasks/traffic/http-traffic-splitting.md
index 06e4a236589..2f3dbdf6e9c 100644
--- a/site/content/en/docs/tasks/traffic/http-traffic-splitting.md
+++ b/site/content/en/docs/tasks/traffic/http-traffic-splitting.md
@@ -6,10 +6,9 @@ The [HTTPRoute][] resource allows one or more [backendRefs][] to be provided. Re
if they match the rules of the HTTPRoute. If an invalid backendRef is configured, then HTTP responses will be returned
with status code `500` for all requests that would have been sent to that backend.
-## Installation
+## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Single backendRef
diff --git a/site/content/en/docs/tasks/traffic/http-urlrewrite.md b/site/content/en/docs/tasks/traffic/http-urlrewrite.md
index 0ebb7595c22..3515bd9caa4 100644
--- a/site/content/en/docs/tasks/traffic/http-urlrewrite.md
+++ b/site/content/en/docs/tasks/traffic/http-urlrewrite.md
@@ -7,8 +7,7 @@ used on a Route rule. This MUST NOT be used on the same Route rule as a HTTPRequ
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Rewrite URL Prefix Path
@@ -276,6 +275,160 @@ $ curl -L -vvv --header "Host: path.rewrite.example" "http://${GATEWAY_HOST}/get
You can see that the `X-Envoy-Original-Path` is `/get/origin/path/extra`, but the actual path is
`/force/replace/fullpath`.
+## Rewrite URL Path with Regex
+
+In addition to core Gateway-API rewrite options, Envoy Gateway supports extended rewrite options through the [HTTPRouteFilter][] API.
+The `HTTPRouteFilter` API can be configured to use [RE2][]-compatible regex matchers and substitutions to rewrite a portion of the url.
+In the example below, requests sent to `http://${GATEWAY_HOST}/service/xxx/yyy` (where `xxx` is a single path portion and `yyy` is one or more path portions)
+are rewritten to `http://${GATEWAY_HOST}/yyy/instance/xxx`. The entire path is matched and rewritten using capture groups.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway.
+
+```shell
+kubectl get httproute/http-filter-url-regex-rewrite -o yaml
+```
+
+Querying `http://${GATEWAY_HOST}/service/foo/v1/api` should rewrite the request to
+`http://${GATEWAY_HOST}/service/foo/v1/api`.
+
+```console
+$ curl -L -vvv --header "Host: path.regex.rewrite.example" "http://${GATEWAY_HOST}/service/foo/v1/api"
+...
+> GET /service/foo/v1/api HTTP/1.1
+> Host: path.regex.rewrite.example
+> User-Agent: curl/8.7.1
+> Accept: */*
+>
+* Request completely sent off
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< date: Mon, 16 Sep 2024 18:49:48 GMT
+< content-length: 482
+<
+{
+ "path": "/v1/api/instance/foo",
+ "host": "path.regex.rewrite.example",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/8.7.1"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "10.244.0.37"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "24a5958f-1bfa-4694-a9c1-807d5139a18a"
+ ]
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-765694d47f-lzmpm"
+...
+```
+
+You can see that the path is rewritten from `/service/foo/v1/api`, to `/v1/api/instance/foo`.
+
## Rewrite Host Name
You can configure to rewrite the hostname like below. In this example, any requests sent to
@@ -402,4 +555,145 @@ $ curl -L -vvv --header "Host: path.rewrite.example" "http://${GATEWAY_HOST}/get
You can see that the `X-Forwarded-Host` is `path.rewrite.example`, but the actual host is `envoygateway.io`.
+## Rewrite URL Host Name by Header or Backend
+
+In addition to core Gateway-API rewrite options, Envoy Gateway supports extended rewrite options through the [HTTPRouteFilter][] API.
+The `HTTPRouteFilter` API can be configured to rewrite the Host header value to:
+- The value of a different request header
+- The DNS name of the backend that the request is routed to
+
+In the following example, the host header is rewritten to the value of the x-custom-host header.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway.
+
+```shell
+kubectl get httproute/http-filter-header-host-rewrite -o yaml
+```
+
+Querying `http://${GATEWAY_HOST}/header` and providing a custom host rewrite header x-custom-host should rewrite the
+request host header to the value of the x-custom-host header.
+
+```console
+$ curl -L -vvv --header "Host: host.header.rewrite.example" --header "x-custom-host: foo" "http://${GATEWAY_HOST}/header"
+...
+> GET /header HTTP/1.1
+> Host: host.header.rewrite.example
+> User-Agent: curl/8.7.1
+> Accept: */*
+> x-custom-host: foo
+>
+* Request completely sent off
+< HTTP/1.1 200 OK
+<
+{
+ "path": "/header",
+ "host": "foo",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "X-Custom-Host": [
+ "foo"
+ ],
+ "X-Forwarded-Host": [
+ "host.header.rewrite.example"
+ ],
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-765694d47f-5t6f2"
+...
+```
+
+You can see that the host is rewritten from `host.header.rewrite.example`, to the value of the provided
+`x-custom-host` header `foo`. The original host header is preserved in the `X-Forwarded-Host` header.
+
+
[HTTPURLRewriteFilter]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPURLRewriteFilter
+[HTTPRouteFilter]: ../../../api/extension_types#httproutefilter
+[RE2]: https://github.com/google/re2/wiki/Syntax
\ No newline at end of file
diff --git a/site/content/en/docs/tasks/traffic/http3.md b/site/content/en/docs/tasks/traffic/http3.md
index 4fe660ddf7e..a0fb1594295 100644
--- a/site/content/en/docs/tasks/traffic/http3.md
+++ b/site/content/en/docs/tasks/traffic/http3.md
@@ -11,8 +11,7 @@ This task uses a self-signed CA, so it should be used for testing and demonstrat
## Installation
-Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## TLS Certificates
@@ -70,10 +69,10 @@ metadata:
name: enable-http3
spec:
http3: {}
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
EOF
```
@@ -89,10 +88,10 @@ metadata:
name: enable-http3
spec:
http3: {}
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
```
{{% /tab %}}
diff --git a/site/content/en/docs/tasks/traffic/load-balancing.md b/site/content/en/docs/tasks/traffic/load-balancing.md
index 90a816e7bc3..3c9a78450b5 100644
--- a/site/content/en/docs/tasks/traffic/load-balancing.md
+++ b/site/content/en/docs/tasks/traffic/load-balancing.md
@@ -13,12 +13,13 @@ Envoy Gateway supports the following load balancing policies:
- **Consistent Hash**: load balancer implements consistent hashing to upstream hosts.
Envoy Gateway introduces a new CRD called [BackendTrafficPolicy][] that allows the user to describe their desired load balancing polices.
-This instantiated resource can be linked to a [Gateway][], [HTTPRoute][] or [GRPCRoute][] resource.
+This instantiated resource can be linked to a [Gateway][], [HTTPRoute][] or [GRPCRoute][] resource. If `loadBalancer` is not specified in [BackendTrafficPolicy][], the default load balancing policy is `Least Request`.
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+### Install Envoy Gateway
+
+{{< boilerplate prerequisites >}}
For better testing the load balancer, you can add more hosts in upstream cluster by increasing the replicas of one deployment:
diff --git a/site/content/en/docs/tasks/traffic/local-rate-limit.md b/site/content/en/docs/tasks/traffic/local-rate-limit.md
index 4284c7e4fe1..05caf07258c 100644
--- a/site/content/en/docs/tasks/traffic/local-rate-limit.md
+++ b/site/content/en/docs/tasks/traffic/local-rate-limit.md
@@ -26,10 +26,7 @@ has its own 100r/s rate limit bucket.
## Prerequisites
-### Install Envoy Gateway
-
-* Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the HTTPRoute example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Rate Limit Specific User
@@ -46,8 +43,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -75,8 +72,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -248,6 +245,227 @@ server: envoy
```
+## Rate Limit Specific User Unless within Test Org
+
+Here is an example of a rate limit implemented by the application developer to limit a specific user by matching on a custom `x-user-id` header
+with a value set to `one`. But the user must not be limited if logging in within Test org, determined by custom header `x-org-id` set to `test`.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+### HTTPRoute
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway.
+
+```shell
+kubectl get httproute/http-ratelimit -o yaml
+```
+
+Get the Gateway's address:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+Let's query `ratelimit.example/get` 4 times with `x-user-id` set to `one` and `x-org-id` set to `org1`. We should receive a `200` response from the example Gateway for the first 3 requests and the last request should be rate limited.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: one" --header "x-org-id: org1" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 429 Too Many Requests
+x-envoy-ratelimited: true
+date: Wed, 08 Feb 2023 02:33:34 GMT
+server: envoy
+transfer-encoding: chunked
+
+```
+
+Let's query `ratelimit.example/get` 4 times with `x-user-id` set to `one` and `x-org-id` set to `test`. We should receive a `200` response from the example Gateway for all the 4 requests, unlike previous example where the last request was rate limited.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: one" --header "x-org-id: test" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+```
+
## Rate Limit All Requests
This example shows you how to rate limit all requests matching the HTTPRoute rule at 3 requests/Hour by leaving the `clientSelectors` field unset.
@@ -262,8 +480,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -287,8 +505,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
diff --git a/site/content/en/docs/tasks/traffic/response-override.md b/site/content/en/docs/tasks/traffic/response-override.md
new file mode 100644
index 00000000000..ea8121bfe89
--- /dev/null
+++ b/site/content/en/docs/tasks/traffic/response-override.md
@@ -0,0 +1,157 @@
+---
+title: "Response Override"
+---
+
+Response Override allows you to override the response from the backend with a custom one. This can be useful for scenarios such as returning a custom 404 page when the requested resource is not found or a custom 500 error message when the backend is failing.
+
+## Installation
+
+Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+## Testing Response Override
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/status/404
+```
+
+```console
+* Trying 127.0.0.1:80...
+* Connected to 172.18.0.200 (172.18.0.200) port 80
+> GET /status/404 HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.5.0
+> Accept: */*
+>
+< HTTP/1.1 404 Not Found
+< content-type: text/plain
+< content-length: 32
+< date: Thu, 07 Nov 2024 09:22:29 GMT
+<
+* Connection #0 to host 172.18.0.200 left intact
+Oops! Your request is not found.
+```
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/status/500
+```
+
+```console
+* Trying 127.0.0.1:80...
+* Connected to 172.18.0.200 (172.18.0.200) port 80
+> GET /status/500 HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.5.0
+> Accept: */*
+>
+< HTTP/1.1 500 Internal Server Error
+< content-type: application/json
+< content-length: 34
+< date: Thu, 07 Nov 2024 09:23:02 GMT
+<
+* Connection #0 to host 172.18.0.200 left intact
+{"error": "Internal Server Error"}
+```
\ No newline at end of file
diff --git a/site/content/en/docs/tasks/traffic/retry.md b/site/content/en/docs/tasks/traffic/retry.md
index 83429f35ed7..75d151bdff6 100644
--- a/site/content/en/docs/tasks/traffic/retry.md
+++ b/site/content/en/docs/tasks/traffic/retry.md
@@ -15,7 +15,7 @@ Envoy Gateway introduces a new CRD called [BackendTrafficPolicy](../../../api/ex
## Prerequisites
-Follow the installation step from the [Quickstart](../../quickstart) to install Envoy Gateway and sample resources.
+{{< boilerplate prerequisites >}}
## Test and customize retry settings
@@ -56,10 +56,10 @@ kind: BackendTrafficPolicy
metadata:
name: retry-for-route
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
retry:
numRetries: 5
perRetry:
@@ -87,10 +87,10 @@ kind: BackendTrafficPolicy
metadata:
name: retry-for-route
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
retry:
numRetries: 5
perRetry:
diff --git a/site/content/en/docs/tasks/traffic/tcp-routing.md b/site/content/en/docs/tasks/traffic/tcp-routing.md
index d36f145e266..0befbd0140d 100644
--- a/site/content/en/docs/tasks/traffic/tcp-routing.md
+++ b/site/content/en/docs/tasks/traffic/tcp-routing.md
@@ -6,10 +6,9 @@ title: "TCP Routing"
connections on the port specified by the listener to a set of backends specified by the TCPRoute. To learn more about
HTTP routing, refer to the [Gateway API documentation][].
-## Installation
+## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Configuration
diff --git a/site/content/en/docs/tasks/traffic/udp-routing.md b/site/content/en/docs/tasks/traffic/udp-routing.md
index b9d8e379282..546b77f9159 100644
--- a/site/content/en/docs/tasks/traffic/udp-routing.md
+++ b/site/content/en/docs/tasks/traffic/udp-routing.md
@@ -12,8 +12,7 @@ For additional information, refer to Envoy's [UDP proxy documentation][].
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
## Installation
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index 9a2cd961a63..5119d756646 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -15,19 +15,14 @@ API group.
### Resource Types
- [Backend](#backend)
-- [BackendList](#backendlist)
- [BackendTrafficPolicy](#backendtrafficpolicy)
-- [BackendTrafficPolicyList](#backendtrafficpolicylist)
- [ClientTrafficPolicy](#clienttrafficpolicy)
-- [ClientTrafficPolicyList](#clienttrafficpolicylist)
- [EnvoyExtensionPolicy](#envoyextensionpolicy)
-- [EnvoyExtensionPolicyList](#envoyextensionpolicylist)
- [EnvoyGateway](#envoygateway)
- [EnvoyPatchPolicy](#envoypatchpolicy)
-- [EnvoyPatchPolicyList](#envoypatchpolicylist)
- [EnvoyProxy](#envoyproxy)
+- [HTTPRouteFilter](#httproutefilter)
- [SecurityPolicy](#securitypolicy)
-- [SecurityPolicyList](#securitypolicylist)
@@ -57,18 +52,16 @@ ALSEnvoyProxyAccessLog defines the gRPC Access Log Service (ALS) sink.
The service must implement the Envoy gRPC Access Log Service streaming API:
https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/accesslog/v3/als.proto
Access log format information is passed in the form of gRPC metadata when the
-stream is established. Specifically, the following metadata is passed:
-
-
-- `x-accesslog-text` - The access log format string when a Text format is used.
-- `x-accesslog-attr` - JSON encoded key/value pairs when a JSON format is used.
+stream is established.
_Appears in:_
- [ProxyAccessLogSink](#proxyaccesslogsink)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs references a Kubernetes object that represents the gRPC service to which the access logs will be sent. Currently only Service is supported. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `logName` | _string_ | false | LogName defines the friendly name of the access log to be returned in StreamAccessLogsMessage.Identifier. This allows the access log server to differentiate between different access logs coming from the same Envoy. |
| `type` | _[ALSEnvoyProxyAccessLogType](#alsenvoyproxyaccesslogtype)_ | true | Type defines the type of accesslog. Supported types are "HTTP" and "TCP". |
| `http` | _[ALSEnvoyProxyHTTPAccessLogConfig](#alsenvoyproxyhttpaccesslogconfig)_ | false | HTTP defines additional configuration specific to HTTP access logs. |
@@ -124,6 +117,7 @@ _Appears in:_
| `type` | _[ActiveHealthCheckerType](#activehealthcheckertype)_ | true | Type defines the type of health checker. |
| `http` | _[HTTPActiveHealthChecker](#httpactivehealthchecker)_ | false | HTTP defines the configuration of http health checker. It's required while the health checker type is HTTP. |
| `tcp` | _[TCPActiveHealthChecker](#tcpactivehealthchecker)_ | false | TCP defines the configuration of tcp health checker. It's required while the health checker type is TCP. |
+| `grpc` | _[GRPCActiveHealthChecker](#grpcactivehealthchecker)_ | false | GRPC defines the configuration of the GRPC health checker. It's optional, and can only be used if the specified type is GRPC. |
#### ActiveHealthCheckPayload
@@ -171,6 +165,7 @@ _Appears in:_
| ----- | ----------- |
| `HTTP` | ActiveHealthCheckerTypeHTTP defines the HTTP type of health checking. |
| `TCP` | ActiveHealthCheckerTypeTCP defines the TCP type of health checking. |
+| `GRPC` | ActiveHealthCheckerTypeGRPC defines the GRPC type of health checking. |
#### AppProtocolType
@@ -234,9 +229,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `name` | _string_ | false | Name is a user-friendly name for the rule. If not specified, Envoy Gateway will generate a unique name for the rule.n |
+| `name` | _string_ | false | Name is a user-friendly name for the rule. If not specified, Envoy Gateway will generate a unique name for the rule. |
| `action` | _[AuthorizationAction](#authorizationaction)_ | true | Action defines the action to be taken if the rule matches. |
-| `principal` | _[Principal](#principal)_ | true | Principal specifies the client identity of a request. |
+| `principal` | _[Principal](#principal)_ | true | Principal specifies the client identity of a request. If there are multiple principal types, all principals must match for the rule to match. For example, if there are two principals: one for client IP and one for JWT claim, the rule will match only if both the client IP and the JWT claim match. |
#### BackOffPolicy
@@ -261,8 +256,7 @@ _Appears in:_
Backend allows the user to configure the endpoints of a backend and
the behavior of the connection from Envoy Proxy to the backend.
-_Appears in:_
-- [BackendList](#backendlist)
+
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -273,6 +267,31 @@ _Appears in:_
| `status` | _[BackendStatus](#backendstatus)_ | true | Status defines the current status of Backend. |
+#### BackendCluster
+
+
+
+BackendCluster contains all the configuration required for configuring access
+to a backend. This can include multiple endpoints, and settings that apply for
+managing the connection to all these endpoints.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OIDCProvider](#oidcprovider)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+
+
@@ -285,10 +304,11 @@ BackendConnection allows users to configure connection-level settings of backend
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit Soft limit on size of the cluster’s connections read and write buffers. If unspecified, an implementation defined default is applied (32768 bytes). For example, 20Mi, 1Gi, 256Ki etc. Note: that when the suffix is not provided, the value is interpreted as bytes. |
+| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit Soft limit on size of the cluster’s connections read and write buffers. BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. If unspecified, an implementation defined default is applied (32768 bytes). For example, 20Mi, 1Gi, 256Ki etc. Note: that when the suffix is not provided, the value is interpreted as bytes. |
#### BackendEndpoint
@@ -305,26 +325,10 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `fqdn` | _[FQDNEndpoint](#fqdnendpoint)_ | false | FQDN defines a FQDN endpoint |
-| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Currently, only IPv4 Addresses are supported. |
+| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Supports both IPv4 and IPv6 addresses. |
| `unix` | _[UnixSocket](#unixsocket)_ | false | Unix defines the unix domain socket endpoint |
-#### BackendList
-
-
-
-BackendList contains a list of Backend resources.
-
-
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`BackendList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[Backend](#backend) array_ | true | |
-
-
#### BackendRef
@@ -333,9 +337,11 @@ BackendRef defines how an ObjectReference that is specific to BackendRef.
_Appears in:_
- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [BackendCluster](#backendcluster)
- [ExtProc](#extproc)
- [GRPCExtAuthService](#grpcextauthservice)
- [HTTPExtAuthService](#httpextauthservice)
+- [OIDCProvider](#oidcprovider)
- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
- [TracingProvider](#tracingprovider)
@@ -347,6 +353,7 @@ _Appears in:_
| `name` | _[ObjectName](#objectname)_ | true | Name is the name of the referent. |
| `namespace` | _[Namespace](#namespace)_ | false | Namespace is the namespace of the backend. When unspecified, the local namespace is inferred.
Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.
Support: Core |
| `port` | _[PortNumber](#portnumber)_ | false | Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. |
+| `fallback` | _boolean_ | false | Fallback indicates whether the backend is designated as a fallback. Multiple fallback backends can be configured. It is highly recommended to configure active or passive health checks to ensure that failover can be detected when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again. The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when the health of the active backends falls below 72%. |
#### BackendSpec
@@ -362,6 +369,7 @@ _Appears in:_
| --- | --- | --- | --- |
| `endpoints` | _[BackendEndpoint](#backendendpoint) array_ | true | Endpoints defines the endpoints to be used when connecting to the backend. |
| `appProtocols` | _[AppProtocolType](#appprotocoltype) array_ | false | AppProtocols defines the application protocols to be supported when connecting to the backend. |
+| `fallback` | _boolean_ | false | Fallback indicates whether the backend is designated as a fallback. It is highly recommended to configure active or passive health checks to ensure that failover can be detected when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again. The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when the health of the active backends falls below 72%. |
#### BackendStatus
@@ -395,7 +403,7 @@ _Appears in:_
| `ciphers` | _string array_ | false | Ciphers specifies the set of cipher suites supported when negotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3. In non-FIPS Envoy Proxy builds the default cipher list is: - [ECDHE-ECDSA-AES128-GCM-SHA256\|ECDHE-ECDSA-CHACHA20-POLY1305] - [ECDHE-RSA-AES128-GCM-SHA256\|ECDHE-RSA-CHACHA20-POLY1305] - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 In builds using BoringSSL FIPS the default cipher list is: - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 |
| `ecdhCurves` | _string array_ | false | ECDHCurves specifies the set of supported ECDH curves. In non-FIPS Envoy Proxy builds the default curves are: - X25519 - P-256 In builds using BoringSSL FIPS the default curve is: - P-256 |
| `signatureAlgorithms` | _string array_ | false | SignatureAlgorithms specifies which signature algorithms the listener should support. |
-| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be exposed by the listener. By default h2 and http/1.1 are enabled. Supported values are: - http/1.0 - http/1.1 - h2 |
+| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be exposed by the listener or used by the proxy to connect to the backend. Defaults: 1. HTTPS Routes: h2 and http/1.1 are enabled in listener context. 2. Other Routes: ALPN is disabled. 3. Backends: proxy uses the appropriate ALPN options for the backend protocol. When an empty list is provided, the ALPN TLS extension is disabled. Supported values are: - http/1.0 - http/1.1 - h2 |
#### BackendTrafficPolicy
@@ -405,8 +413,7 @@ _Appears in:_
BackendTrafficPolicy allows the user to configure the behavior of the connection
between the Envoy Proxy listener and the backend service.
-_Appears in:_
-- [BackendTrafficPolicyList](#backendtrafficpolicylist)
+
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -417,24 +424,6 @@ _Appears in:_
| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | status defines the current status of BackendTrafficPolicy. |
-
-
-#### BackendTrafficPolicyList
-
-
-
-BackendTrafficPolicyList contains a list of BackendTrafficPolicy resources.
-
-
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`BackendTrafficPolicyList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[BackendTrafficPolicy](#backendtrafficpolicy) array_ | true | |
-
-
#### BackendTrafficPolicySpec
@@ -449,17 +438,20 @@ _Appears in:_
| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to. This policy and the TargetRef MUST be in the same namespace for this Policy to have effect
Deprecated: use targetRefs/targetSelectors instead |
| `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy is being attached to. |
| `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels |
-| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. |
-| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints |
+| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints. Defaults to `LeastRequest`. |
+| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. |
| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection. Disabled by default. |
| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. |
-| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to inject delays and abort requests to mimic failure scenarios such as service failures and overloads |
| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests. If not set, circuit breakers will be enabled with the default thresholds |
-| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
-| `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using the same HTTP protocol that the incoming request used. Defaults to false, which means that Envoy will use the protocol indicated by the attached BackendRef. |
| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. |
| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. |
+| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. |
+| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. |
+| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. |
+| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to inject delays and abort requests to mimic failure scenarios such as service failures and overloads |
+| `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using the same HTTP protocol that the incoming request used. Defaults to false, which means that Envoy will use the protocol indicated by the attached BackendRef. |
+| `responseOverride` | _[ResponseOverride](#responseoverride) array_ | false | ResponseOverride defines the configuration to override specific responses with a custom one. If multiple configurations are specified, the first one to match wins. |
#### BasicAuth
@@ -476,6 +468,20 @@ _Appears in:_
| `users` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the username-password pairs in htpasswd format, used to verify user credentials in the "Authorization" header.
This is an Opaque secret. The username-password pairs should be stored in the key ".htpasswd". As the key name indicates, the value needs to be the htpasswd format, for example: "user1:\{SHA\}hashed_user1_password". Right now, only SHA hash algorithm is supported. Reference to https://httpd.apache.org/docs/2.4/programs/htpasswd.html for more details.
Note: The secret must be in the same namespace as the SecurityPolicy. |
+#### BodyToExtAuth
+
+
+
+BodyToExtAuth defines the Body to Ext Auth configuration
+
+_Appears in:_
+- [ExtAuth](#extauth)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `maxRequestBytes` | _integer_ | true | MaxRequestBytes is the maximum size of a message body that the filter will hold in memory. Envoy will return HTTP 413 and will not initiate the authorization process when buffer reaches the number set in this field. Note that this setting will have precedence over failOpen mode. |
+
+
#### BootstrapType
_Underlying type:_ _string_
@@ -489,6 +495,7 @@ _Appears in:_
| ----- | ----------- |
| `Merge` | Merge merges the provided bootstrap with the default one. The provided bootstrap can add or override a value within a map, or add a new value to a list. Please note that the provided bootstrap can't override a value within a list. |
| `Replace` | Replace replaces the default bootstrap with the provided one. |
+| `JSONPatch` | JSONPatch applies the provided JSONPatches to the default bootstrap. |
#### CIDR
@@ -500,6 +507,7 @@ A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address
_Appears in:_
- [Principal](#principal)
+- [XForwardedForSettings](#xforwardedforsettings)
@@ -514,12 +522,12 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `allowOrigins` | _[Origin](#origin) array_ | true | AllowOrigins defines the origins that are allowed to make requests. |
-| `allowMethods` | _string array_ | true | AllowMethods defines the methods that are allowed to make requests. |
-| `allowHeaders` | _string array_ | true | AllowHeaders defines the headers that are allowed to be sent with requests. |
-| `exposeHeaders` | _string array_ | true | ExposeHeaders defines the headers that can be exposed in the responses. |
-| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | MaxAge defines how long the results of a preflight request can be cached. |
-| `allowCredentials` | _boolean_ | true | AllowCredentials indicates whether a request can include user credentials like cookies, authentication headers, or TLS client certificates. |
+| `allowOrigins` | _[Origin](#origin) array_ | false | AllowOrigins defines the origins that are allowed to make requests. It specifies the allowed origins in the Access-Control-Allow-Origin CORS response header. The value "*" allows any origin to make requests. |
+| `allowMethods` | _string array_ | false | AllowMethods defines the methods that are allowed to make requests. It specifies the allowed methods in the Access-Control-Allow-Methods CORS response header.. The value "*" allows any method to be used. |
+| `allowHeaders` | _string array_ | false | AllowHeaders defines the headers that are allowed to be sent with requests. It specifies the allowed headers in the Access-Control-Allow-Headers CORS response header.. The value "*" allows any header to be sent. |
+| `exposeHeaders` | _string array_ | false | ExposeHeaders defines which response headers should be made accessible to scripts running in the browser. It specifies the headers in the Access-Control-Expose-Headers CORS response header.. The value "*" allows any header to be exposed. |
+| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MaxAge defines how long the results of a preflight request can be cached. It specifies the value in the Access-Control-Max-Age CORS response header.. |
+| `allowCredentials` | _boolean_ | false | AllowCredentials indicates whether a request can include user credentials like cookies, authentication headers, or TLS client certificates. It specifies the value in the Access-Control-Allow-Credentials CORS response header. |
#### CircuitBreaker
@@ -530,6 +538,7 @@ CircuitBreaker defines the Circuit Breaker configuration.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -567,7 +576,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `connectionLimit` | _[ConnectionLimit](#connectionlimit)_ | false | ConnectionLimit defines limits related to connections |
-| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit provides configuration for the maximum buffer size in bytes for each incoming connection. For example, 20Mi, 1Gi, 256Ki etc. Note that when the suffix is not provided, the value is interpreted as bytes. Default: 32768 bytes. |
+| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit provides configuration for the maximum buffer size in bytes for each incoming connection. BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. For example, 20Mi, 1Gi, 256Ki etc. Note that when the suffix is not provided, the value is interpreted as bytes. Default: 32768 bytes. |
#### ClientIPDetectionSettings
@@ -602,7 +611,8 @@ _Appears in:_
| `ciphers` | _string array_ | false | Ciphers specifies the set of cipher suites supported when negotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3. In non-FIPS Envoy Proxy builds the default cipher list is: - [ECDHE-ECDSA-AES128-GCM-SHA256\|ECDHE-ECDSA-CHACHA20-POLY1305] - [ECDHE-RSA-AES128-GCM-SHA256\|ECDHE-RSA-CHACHA20-POLY1305] - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 In builds using BoringSSL FIPS the default cipher list is: - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 |
| `ecdhCurves` | _string array_ | false | ECDHCurves specifies the set of supported ECDH curves. In non-FIPS Envoy Proxy builds the default curves are: - X25519 - P-256 In builds using BoringSSL FIPS the default curve is: - P-256 |
| `signatureAlgorithms` | _string array_ | false | SignatureAlgorithms specifies which signature algorithms the listener should support. |
-| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be exposed by the listener. By default h2 and http/1.1 are enabled. Supported values are: - http/1.0 - http/1.1 - h2 |
+| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be exposed by the listener or used by the proxy to connect to the backend. Defaults: 1. HTTPS Routes: h2 and http/1.1 are enabled in listener context. 2. Other Routes: ALPN is disabled. 3. Backends: proxy uses the appropriate ALPN options for the backend protocol. When an empty list is provided, the ALPN TLS extension is disabled. Supported values are: - http/1.0 - http/1.1 - h2 |
+| `session` | _[Session](#session)_ | false | Session defines settings related to TLS session management. |
#### ClientTimeout
@@ -627,8 +637,7 @@ _Appears in:_
ClientTrafficPolicy allows the user to configure the behavior of the connection
between the downstream client and Envoy Proxy listener.
-_Appears in:_
-- [ClientTrafficPolicyList](#clienttrafficpolicylist)
+
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -639,22 +648,6 @@ _Appears in:_
| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of ClientTrafficPolicy. |
-#### ClientTrafficPolicyList
-
-
-
-ClientTrafficPolicyList contains a list of ClientTrafficPolicy resources.
-
-
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`ClientTrafficPolicyList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[ClientTrafficPolicy](#clienttrafficpolicy) array_ | true | |
-
-
#### ClientTrafficPolicySpec
@@ -700,6 +693,39 @@ _Appears in:_
| `caCertificateRefs` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference) array_ | false | CACertificateRefs contains one or more references to Kubernetes objects that contain TLS certificates of the Certificate Authorities that can be used as a trust anchor to validate the certificates presented by the client.
A single reference to a Kubernetes ConfigMap or a Kubernetes Secret, with the CA certificate in a key named `ca.crt` is currently supported.
References to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. |
+#### ClusterSettings
+
+
+
+ClusterSettings provides the various knobs that can be set to control how traffic to a given
+backend will be configured.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [BackendCluster](#backendcluster)
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OIDCProvider](#oidcprovider)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints. Defaults to `LeastRequest`. |
+| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
+| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. |
+| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection. Disabled by default. |
+| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. |
+| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests. If not set, circuit breakers will be enabled with the default thresholds |
+| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. |
+| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. |
+| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. |
+| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. |
+
+
#### Compression
@@ -739,7 +765,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `value` | _integer_ | true | Value of the maximum concurrent connections limit. When the limit is reached, incoming connections will be closed after the CloseDelay duration. Default: unlimited. |
+| `value` | _integer_ | true | Value of the maximum concurrent connections limit. When the limit is reached, incoming connections will be closed after the CloseDelay duration. |
| `closeDelay` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | CloseDelay defines the delay to use before closing connections that are rejected once the limit value is reached. Default: none. |
@@ -812,6 +838,52 @@ _Appears in:_
| `failClosed` | _boolean_ | false | FailClosed is a switch used to control the flow of traffic when client IP detection fails. If set to true, the listener will respond with 403 Forbidden when the client IP address cannot be determined. |
+#### CustomResponse
+
+
+
+CustomResponse defines the configuration for returning a custom response.
+
+_Appears in:_
+- [ResponseOverride](#responseoverride)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `contentType` | _string_ | false | Content Type of the response. This will be set in the Content-Type header. |
+| `body` | _[CustomResponseBody](#customresponsebody)_ | true | Body of the Custom Response |
+
+
+#### CustomResponseBody
+
+
+
+CustomResponseBody
+
+_Appears in:_
+- [CustomResponse](#customresponse)
+- [HTTPDirectResponseFilter](#httpdirectresponsefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[ResponseValueType](#responsevaluetype)_ | true | Type is the type of method to use to read the body value. Valid values are Inline and ValueRef, default is Inline. |
+| `inline` | _string_ | false | Inline contains the value as an inline string. |
+| `valueRef` | _[LocalObjectReference](#localobjectreference)_ | false | ValueRef contains the contents of the body specified as a local object reference. Only a reference to ConfigMap is supported.
The value of key `response.body` in the ConfigMap will be used as the response body. If the key is not found, the first value in the ConfigMap will be used. |
+
+
+#### CustomResponseMatch
+
+
+
+CustomResponseMatch defines the configuration for matching a user response to return a custom one.
+
+_Appears in:_
+- [ResponseOverride](#responseoverride)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `statusCodes` | _[StatusCodeMatch](#statuscodematch) array_ | true | Status code to match on. The match evaluates to true if any of the matches are successful. |
+
+
#### CustomTag
@@ -845,53 +917,52 @@ _Appears in:_
| `RequestHeader` | CustomTagTypeRequestHeader adds value from request header to each span. |
-#### EnvironmentCustomTag
+#### DNS
+
-EnvironmentCustomTag adds value from environment variable to each span.
_Appears in:_
-- [CustomTag](#customtag)
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `name` | _string_ | true | Name defines the name of the environment variable which to extract the value from. |
-| `defaultValue` | _string_ | false | DefaultValue defines the default value to use if the environment variable is not set. |
+| `dnsRefreshRate` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | DNSRefreshRate specifies the rate at which DNS records should be refreshed. Defaults to 30 seconds. |
+| `respectDnsTtl` | _boolean_ | true | RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. Defaults to true. |
-#### EnvoyExtensionPolicy
+#### EnvironmentCustomTag
-EnvoyExtensionPolicy allows the user to configure various envoy extensibility options for the Gateway.
+EnvironmentCustomTag adds value from environment variable to each span.
_Appears in:_
-- [EnvoyExtensionPolicyList](#envoyextensionpolicylist)
+- [CustomTag](#customtag)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`EnvoyExtensionPolicy`
-| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `spec` | _[EnvoyExtensionPolicySpec](#envoyextensionpolicyspec)_ | true | Spec defines the desired state of EnvoyExtensionPolicy. |
-| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of EnvoyExtensionPolicy. |
+| `name` | _string_ | true | Name defines the name of the environment variable which to extract the value from. |
+| `defaultValue` | _string_ | false | DefaultValue defines the default value to use if the environment variable is not set. |
-#### EnvoyExtensionPolicyList
+#### EnvoyExtensionPolicy
-EnvoyExtensionPolicyList contains a list of EnvoyExtensionPolicy resources.
+EnvoyExtensionPolicy allows the user to configure various envoy extensibility options for the Gateway.
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`EnvoyExtensionPolicyList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[EnvoyExtensionPolicy](#envoyextensionpolicy) array_ | true | |
+| `kind` | _string_ | |`EnvoyExtensionPolicy`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[EnvoyExtensionPolicySpec](#envoyextensionpolicyspec)_ | true | Spec defines the desired state of EnvoyExtensionPolicy. |
+| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of EnvoyExtensionPolicy. |
#### EnvoyExtensionPolicySpec
@@ -930,11 +1001,13 @@ _Appears in:_
| `envoy.filters.http.basic_auth` | EnvoyFilterBasicAuth defines the Envoy HTTP basic authentication filter. |
| `envoy.filters.http.oauth2` | EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter. |
| `envoy.filters.http.jwt_authn` | EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter. |
+| `envoy.filters.http.stateful_session` | EnvoyFilterSessionPersistence defines the Envoy HTTP session persistence filter. |
| `envoy.filters.http.ext_proc` | EnvoyFilterExtProc defines the Envoy HTTP external process filter. |
| `envoy.filters.http.wasm` | EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter. |
| `envoy.filters.http.rbac` | EnvoyFilterRBAC defines the Envoy RBAC filter. |
| `envoy.filters.http.local_ratelimit` | EnvoyFilterLocalRateLimit defines the Envoy HTTP local rate limit filter. |
| `envoy.filters.http.ratelimit` | EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter. |
+| `envoy.filters.http.custom_response` | EnvoyFilterCustomResponse defines the Envoy HTTP custom response filter. |
| `envoy.filters.http.router` | EnvoyFilterRouter defines the Envoy HTTP router filter. |
@@ -1004,7 +1077,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `resource` | _[EnvoyGatewayResourceProvider](#envoygatewayresourceprovider)_ | true | Resource defines the desired resource provider. This provider is used to specify the provider to be used to retrieve the resource configurations such as Gateway API resources |
-| `infrastructure` | _[EnvoyGatewayInfrastructureProvider](#envoygatewayinfrastructureprovider)_ | true | Infrastructure defines the desired infrastructure provider. This provider is used to specify the provider to be used to provide an environment to deploy the out resources like the Envoy Proxy data plane. |
+| `infrastructure` | _[EnvoyGatewayInfrastructureProvider](#envoygatewayinfrastructureprovider)_ | false | Infrastructure defines the desired infrastructure provider. This provider is used to specify the provider to be used to provide an environment to deploy the out resources like the Envoy Proxy data plane.
Infrastructure is optional, if provider is not specified, No infrastructure provider is available. |
#### EnvoyGatewayFileResourceProvider
@@ -1018,7 +1091,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `paths` | _string array_ | true | Paths are the paths to a directory or file containing the resource configuration. Recursive sub directories are not currently supported. |
+| `paths` | _string array_ | true | Paths are the paths to a directory or file containing the resource configuration. Recursive subdirectories are not currently supported. |
#### EnvoyGatewayHostInfrastructureProvider
@@ -1176,9 +1249,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `type` | _[ProviderType](#providertype)_ | true | Type is the type of provider to use. Supported types are "Kubernetes". |
+| `type` | _[ProviderType](#providertype)_ | true | Type is the type of provider to use. Supported types are "Kubernetes", "Custom". |
| `kubernetes` | _[EnvoyGatewayKubernetesProvider](#envoygatewaykubernetesprovider)_ | false | Kubernetes defines the configuration of the Kubernetes provider. Kubernetes provides runtime configuration via the Kubernetes API. |
-| `custom` | _[EnvoyGatewayCustomProvider](#envoygatewaycustomprovider)_ | false | Custom defines the configuration for the Custom provider. This provider allows you to define a specific resource provider and a infrastructure provider. |
+| `custom` | _[EnvoyGatewayCustomProvider](#envoygatewaycustomprovider)_ | false | Custom defines the configuration for the Custom provider. This provider allows you to define a specific resource provider and an infrastructure provider. |
#### EnvoyGatewayResourceProvider
@@ -1257,8 +1330,7 @@ _Appears in:_
EnvoyPatchPolicy allows the user to modify the generated Envoy xDS
resources by Envoy Gateway using this patch API
-_Appears in:_
-- [EnvoyPatchPolicyList](#envoypatchpolicylist)
+
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -1269,22 +1341,6 @@ _Appears in:_
| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of EnvoyPatchPolicy. |
-#### EnvoyPatchPolicyList
-
-
-
-EnvoyPatchPolicyList contains a list of EnvoyPatchPolicy resources.
-
-
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`EnvoyPatchPolicyList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[EnvoyPatchPolicy](#envoypatchpolicy) array_ | true | |
-
-
#### EnvoyPatchPolicySpec
@@ -1388,8 +1444,9 @@ _Appears in:_
| `extraArgs` | _string array_ | false | ExtraArgs defines additional command line options that are provided to Envoy. More info: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#command-line-options Note: some command line options are used internally(e.g. --log-level) so they cannot be provided here. |
| `mergeGateways` | _boolean_ | false | MergeGateways defines if Gateway resources should be merged onto the same Envoy Proxy Infrastructure. Setting this field to true would merge all Gateway Listeners under the parent Gateway Class. This means that the port, protocol and hostname tuple must be unique for every listener. If a duplicate listener is detected, the newer listener (based on timestamp) will be rejected and its status will be updated with a "Accepted=False" condition. |
| `shutdown` | _[ShutdownConfig](#shutdownconfig)_ | false | Shutdown defines configuration for graceful envoy shutdown process. |
-| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. The FilterPosition in the list will be applied in the order they are defined. If unspecified, the default filter order is applied. Default filter order is:
- envoy.filters.http.health_check
- envoy.filters.http.fault
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.router
Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. |
+| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. The FilterPosition in the list will be applied in the order they are defined. If unspecified, the default filter order is applied. Default filter order is:
- envoy.filters.http.health_check
- envoy.filters.http.fault
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.custom_response
- envoy.filters.http.router
Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. |
| `backendTLS` | _[BackendTLSConfig](#backendtlsconfig)_ | false | BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends. These settings are applied on backends for which TLS policies are specified. |
+| `ipFamily` | _[IPFamily](#ipfamily)_ | false | IPFamily specifies the IP family for the EnvoyProxy fleet. This setting only affects the Gateway listener port and does not impact other aspects of the Envoy proxy configuration. If not specified, the system will operate as follows: - It defaults to IPv4 only. - IPv6 and dual-stack environments are not supported in this default configuration. Note: To enable IPv6 or dual-stack functionality, explicit configuration is required. |
#### EnvoyProxyStatus
@@ -1435,7 +1492,9 @@ _Appears in:_
| `grpc` | _[GRPCExtAuthService](#grpcextauthservice)_ | true | GRPC defines the gRPC External Authorization service. Either GRPCService or HTTPService must be specified, and only one of them can be provided. |
| `http` | _[HTTPExtAuthService](#httpextauthservice)_ | true | HTTP defines the HTTP External Authorization service. Either GRPCService or HTTPService must be specified, and only one of them can be provided. |
| `headersToExtAuth` | _string array_ | false | HeadersToExtAuth defines the client request headers that will be included in the request to the external authorization service. Note: If not specified, the default behavior for gRPC and HTTP external authorization services is different due to backward compatibility reasons. All headers will be included in the check request to a gRPC authorization server. Only the following headers will be included in the check request to an HTTP authorization server: Host, Method, Path, Content-Length, and Authorization. And these headers will always be included to the check request to an HTTP authorization server by default, no matter whether they are specified in HeadersToExtAuth or not. |
+| `bodyToExtAuth` | _[BodyToExtAuth](#bodytoextauth)_ | false | BodyToExtAuth defines the Body to Ext Auth configuration. |
| `failOpen` | _boolean_ | false | FailOpen is a switch used to control the behavior when a response from the External Authorization service cannot be obtained. If FailOpen is set to true, the system allows the traffic to pass through. Otherwise, if it is set to false or not set (defaulting to false), the system blocks the traffic and returns a HTTP 5xx error, reflecting a fail-closed approach. This setting determines whether to prioritize accessibility over strict security in case of authorization service failure. |
+| `recomputeRoute` | _boolean_ | false | RecomputeRoute clears the route cache and recalculates the routing decision. This field must be enabled if the headers added or modified by the ExtAuth are used for route matching decisions. If the recomputation selects a new route, features targeting the new matched route will be applied. |
#### ExtProc
@@ -1449,7 +1508,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs defines the configuration of the external processing service |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `messageTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | MessageTimeout is the timeout for a response to be returned from the external processor Default: 200ms |
| `failOpen` | _boolean_ | false | FailOpen defines if requests or responses that cannot be processed due to connectivity to the external processor are terminated or passed-through. Default: false |
| `processingMode` | _[ExtProcProcessingMode](#extprocprocessingmode)_ | false | ProcessingMode defines how request and response body is processed Default: header and body are not sent to the external processor |
@@ -1548,7 +1609,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `fqdn` | _[FQDNEndpoint](#fqdnendpoint)_ | false | FQDN defines a FQDN endpoint |
-| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Currently, only IPv4 Addresses are supported. |
+| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Supports both IPv4 and IPv6 addresses. |
| `unix` | _[UnixSocket](#unixsocket)_ | false | Unix defines the unix domain socket endpoint |
| `host` | _string_ | false | Host define the extension service hostname. Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix) |
| `port` | _integer_ | false | Port defines the port the extension service is exposed on. Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix) |
@@ -1663,6 +1724,20 @@ _Appears in:_
| `after` | _[EnvoyFilter](#envoyfilter)_ | true | After defines the filter that should come after the filter. Only one of Before or After must be set. |
+#### GRPCActiveHealthChecker
+
+
+
+GRPCActiveHealthChecker defines the settings of the GRPC health check.
+
+_Appears in:_
+- [ActiveHealthCheck](#activehealthcheck)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `service` | _string_ | false | Service to send in the health check request. If this is not specified, then the health check request applies to the entire server and not to a specific service. |
+
+
#### GRPCExtAuthService
@@ -1676,8 +1751,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now.
Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
#### Gateway
@@ -1773,16 +1849,19 @@ _Appears in:_
-HTTP2Settings provides HTTP/2 configuration on the listener.
+HTTP2Settings provides HTTP/2 configuration for listeners and backends.
_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `initialStreamWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams. If not set, the default value is 64 KiB(64*1024). |
| `initialConnectionWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. If not set, the default value is 1 MiB. |
| `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. If not set, the default value is 100. |
+| `onInvalidMessage` | _[InvalidMessageAction](#invalidmessageaction)_ | false | OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error It's recommended for L2 Envoy deployments to set this value to TerminateStream. https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two Default: TerminateConnection |
#### HTTP3Settings
@@ -1828,6 +1907,22 @@ _Appears in:_
| `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | IdleTimeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. Default: 1 hour. |
+#### HTTPDirectResponseFilter
+
+
+
+HTTPDirectResponseFilter defines the configuration to return a fixed response.
+
+_Appears in:_
+- [HTTPRouteFilterSpec](#httproutefilterspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `contentType` | _string_ | false | Content Type of the response. This will be set in the Content-Type header. |
+| `body` | _[CustomResponseBody](#customresponsebody)_ | false | Body of the Response |
+| `statusCode` | _integer_ | false | Status Code of the HTTP response If unset, defaults to 200. |
+
+
#### HTTPExtAuthService
@@ -1839,12 +1934,104 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now.
Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `path` | _string_ | true | Path is the path of the HTTP External Authorization service. If path is specified, the authorization request will be sent to that path, or else the authorization request will be sent to the root path. |
| `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added to the original client request before sending it to the backend server. Note that coexisting headers will be overridden. If not specified, no authorization response headers will be added to the original client request. |
+#### HTTPHostnameModifier
+
+
+
+
+
+_Appears in:_
+- [HTTPURLRewriteFilter](#httpurlrewritefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[HTTPHostnameModifierType](#httphostnamemodifiertype)_ | true | |
+| `header` | _string_ | false | Header is the name of the header whose value would be used to rewrite the Host header |
+
+
+#### HTTPHostnameModifierType
+
+_Underlying type:_ _string_
+
+HTTPPathModifierType defines the type of Hostname rewrite.
+
+_Appears in:_
+- [HTTPHostnameModifier](#httphostnamemodifier)
+
+| Value | Description |
+| ----- | ----------- |
+| `Header` | HeaderHTTPHostnameModifier indicates that the Host header value would be replaced with the value of the header specified in header. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-header |
+| `Backend` | BackendHTTPHostnameModifier indicates that the Host header value would be replaced by the DNS name of the backend if it exists. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-auto-host-rewrite |
+
+
+#### HTTPPathModifier
+
+
+
+
+
+_Appears in:_
+- [HTTPURLRewriteFilter](#httpurlrewritefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[HTTPPathModifierType](#httppathmodifiertype)_ | true | |
+| `replaceRegexMatch` | _[ReplaceRegexMatch](#replaceregexmatch)_ | false | ReplaceRegexMatch defines a path regex rewrite. The path portions matched by the regex pattern are replaced by the defined substitution. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-regex-rewrite Some examples: (1) replaceRegexMatch: pattern: ^/service/([^/]+)(/.*)$ substitution: \2/instance/\1 Would transform /service/foo/v1/api into /v1/api/instance/foo. (2) replaceRegexMatch: pattern: one substitution: two Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/two/zzz. (3) replaceRegexMatch: pattern: ^(.*?)one(.*)$ substitution: \1two\2 Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/one/zzz. (3) replaceRegexMatch: pattern: (?i)/xxx/ substitution: /yyy/ Would transform path /aaa/XxX/bbb into /aaa/yyy/bbb (case-insensitive). |
+
+
+#### HTTPPathModifierType
+
+_Underlying type:_ _string_
+
+HTTPPathModifierType defines the type of path redirect or rewrite.
+
+_Appears in:_
+- [HTTPPathModifier](#httppathmodifier)
+
+| Value | Description |
+| ----- | ----------- |
+| `ReplaceRegexMatch` | RegexHTTPPathModifier This type of modifier indicates that the portions of the path that match the specified regex would be substituted with the specified substitution value https://www.envoyproxy.io/docs/envoy/latest/api-v3/type/matcher/v3/regex.proto#type-matcher-v3-regexmatchandsubstitute |
+
+
+#### HTTPRouteFilter
+
+
+
+HTTPRouteFilter is a custom Envoy Gateway HTTPRouteFilter which provides extended
+traffic processing options such as path regex rewrite, direct response and more.
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`HTTPRouteFilter`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[HTTPRouteFilterSpec](#httproutefilterspec)_ | true | Spec defines the desired state of HTTPRouteFilter. |
+
+
+#### HTTPRouteFilterSpec
+
+
+
+HTTPRouteFilterSpec defines the desired state of HTTPRouteFilter.
+
+_Appears in:_
+- [HTTPRouteFilter](#httproutefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `urlRewrite` | _[HTTPURLRewriteFilter](#httpurlrewritefilter)_ | false | |
+| `directResponse` | _[HTTPDirectResponseFilter](#httpdirectresponsefilter)_ | false | |
+
+
#### HTTPStatus
_Underlying type:_ _integer_
@@ -1870,6 +2057,22 @@ _Appears in:_
| --- | --- | --- | --- |
| `connectionIdleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. Default: 1 hour. |
| `maxConnectionDuration` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The maximum duration of an HTTP connection. Default: unlimited. |
+| `requestTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | RequestTimeout is the time until which entire response is received from the upstream. |
+
+
+#### HTTPURLRewriteFilter
+
+
+
+HTTPURLRewriteFilter define rewrites of HTTP URL components such as path and host
+
+_Appears in:_
+- [HTTPRouteFilterSpec](#httproutefilterspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `hostname` | _[HTTPHostnameModifier](#httphostnamemodifier)_ | false | Hostname is the value to be used to replace the Host header value during forwarding. |
+| `path` | _[HTTPPathModifier](#httppathmodifier)_ | false | Path defines a path rewrite. |
#### HTTPWasmCodeSource
@@ -1902,6 +2105,21 @@ _Appears in:_
| `name` | _string_ | true | Name of the header to hash. |
+#### HeaderMatch
+
+
+
+HeaderMatch defines the match attributes within the HTTP Headers of the request.
+
+_Appears in:_
+- [RateLimitSelectCondition](#ratelimitselectcondition)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[HeaderMatchType](#headermatchtype)_ | false | Type specifies how to match against the value of the header. |
+| `name` | _string_ | true | Name of the HTTP header. |
+| `value` | _string_ | false | Value within the HTTP header. Due to the case-insensitivity of header names, "foo" and "Foo" are considered equivalent. Do not set this field when Type="Distinct", implying matching on any/all unique values within the header. |
+| `invert` | _boolean_ | false | Invert specifies whether the value match result will be inverted. Do not set this field when Type="Distinct", implying matching on any/all unique values within the header. |
#### HeaderMatchType
@@ -1937,6 +2155,7 @@ _Appears in:_
| `xForwardedClientCert` | _[XForwardedClientCert](#xforwardedclientcert)_ | false | XForwardedClientCert configures how Envoy Proxy handle the x-forwarded-client-cert (XFCC) HTTP header.
x-forwarded-client-cert (XFCC) is an HTTP header used to forward the certificate information of part or all of the clients or proxies that a request has flowed through, on its way from the client to the server.
Envoy proxy may choose to sanitize/append/forward the XFCC header before proxying the request.
If not set, the default behavior is sanitizing the XFCC header. |
| `withUnderscoresAction` | _[WithUnderscoresAction](#withunderscoresaction)_ | false | WithUnderscoresAction configures the action to take when an HTTP header with underscores is encountered. The default action is to reject the request. |
| `preserveXRequestID` | _boolean_ | false | PreserveXRequestID configures Envoy to keep the X-Request-ID header if passed for a request that is edge (Edge request is the request from external clients to front Envoy) and not reset it, which is the current Envoy behaviour. It defaults to false. |
+| `earlyRequestHeaders` | _[HTTPHeaderFilter](#httpheaderfilter)_ | false | EarlyRequestHeaders defines settings for early request header modification, before envoy performs routing, tracing and built-in header manipulation. |
#### HealthCheck
@@ -1948,6 +2167,7 @@ are healthy and can be used for routing.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -1982,10 +2202,26 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `address` | _string_ | true | Address defines the IP address of the backend endpoint. |
+| `address` | _string_ | true | Address defines the IP address of the backend endpoint. Supports both IPv4 and IPv6 addresses. |
| `port` | _integer_ | true | Port defines the port of the backend endpoint. |
+#### IPFamily
+
+_Underlying type:_ _string_
+
+IPFamily defines the IP family to use for the Envoy proxy.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Value | Description |
+| ----- | ----------- |
+| `IPv4` | IPv4 defines the IPv4 family. |
+| `IPv6` | IPv6 defines the IPv6 family. |
+| `DualStack` | DualStack defines the dual-stack family. When set to DualStack, Envoy proxy will listen on both IPv4 and IPv6 addresses for incoming client traffic, enabling support for both IP protocol versions. |
+
+
#### ImagePullPolicy
_Underlying type:_ _string_
@@ -2031,6 +2267,21 @@ _Appears in:_
| `Host` | InfrastructureProviderTypeHost defines the "Host" provider. |
+#### InvalidMessageAction
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [HTTP2Settings](#http2settings)
+
+| Value | Description |
+| ----- | ----------- |
+| `TerminateConnection` | |
+| `TerminateStream` | |
+
+
#### JSONPatchOperation
@@ -2040,11 +2291,13 @@ https://datatracker.ietf.org/doc/html/rfc6902
_Appears in:_
- [EnvoyJSONPatchConfig](#envoyjsonpatchconfig)
+- [ProxyBootstrap](#proxybootstrap)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `op` | _[JSONPatchOperationType](#jsonpatchoperationtype)_ | true | Op is the type of operation to perform |
-| `path` | _string_ | true | Path is the location of the target document/field where the operation will be performed Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
+| `path` | _string_ | false | Path is a JSONPointer expression. Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. It specifies the location of the target document/field where the operation will be performed |
+| `jsonPath` | _string_ | false | JSONPath is a JSONPath expression. Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details. It produces one or more JSONPointer expressions based on the given JSON document. If no JSONPointer is found, it will result in an error. If the 'Path' property is also set, it will be appended to the resulting JSONPointer expressions from the JSONPath evaluation. This is useful when creating a property that does not yet exist in the JSON document. The final JSONPointer expressions specifies the locations in the target document/field where the operation will be applied. |
| `from` | _string_ | false | From is the source location of the value to be copied or moved. Only valid for move or copy operations Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
| `value` | _[JSON](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#json-v1-apiextensions-k8s-io)_ | false | Value is the new value of the path location. The value is only used by the `add` and `replace` operations. |
@@ -2075,6 +2328,37 @@ _Appears in:_
| `providers` | _[JWTProvider](#jwtprovider) array_ | true | Providers defines the JSON Web Token (JWT) authentication provider type. When multiple JWT providers are specified, the JWT is considered valid if any of the providers successfully validate the JWT. For additional details, see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html. |
+#### JWTClaim
+
+
+
+JWTClaim specifies a claim in a JWT token.
+
+_Appears in:_
+- [JWTPrincipal](#jwtprincipal)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | true | Name is the name of the claim. If it is a nested claim, use a dot (.) separated string as the name to represent the full path to the claim. For example, if the claim is in the "department" field in the "organization" field, the name should be "organization.department". |
+| `valueType` | _[JWTClaimValueType](#jwtclaimvaluetype)_ | false | ValueType is the type of the claim value. Only String and StringArray types are supported for now. |
+| `values` | _string array_ | true | Values are the values that the claim must match. If the claim is a string type, the specified value must match exactly. If the claim is a string array type, the specified value must match one of the values in the array. If multiple values are specified, one of the values must match for the rule to match. |
+
+
+#### JWTClaimValueType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [JWTClaim](#jwtclaim)
+
+| Value | Description |
+| ----- | ----------- |
+| `String` | |
+| `StringArray` | |
+
+
#### JWTExtractor
@@ -2108,6 +2392,24 @@ _Appears in:_
| `valuePrefix` | _string_ | false | ValuePrefix is the prefix that should be stripped before extracting the token. The format would be used by Envoy like "\{ValuePrefix\}". For example, "Authorization: Bearer ", then the ValuePrefix="Bearer " with a space at the end. |
+#### JWTPrincipal
+
+
+
+JWTPrincipal specifies the client identity of a request based on the JWT claims and scopes.
+At least one of the claims or scopes must be specified.
+Claims and scopes are And-ed together if both are specified.
+
+_Appears in:_
+- [Principal](#principal)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `provider` | _string_ | true | Provider is the name of the JWT provider that used to verify the JWT token. In order to use JWT claims for authorization, you must configure the JWT authentication with the same provider in the same `SecurityPolicy`. |
+| `claims` | _[JWTClaim](#jwtclaim) array_ | false | Claims are the claims in a JWT token.
If multiple claims are specified, all claims must match for the rule to match. For example, if there are two claims: one for the audience and one for the issuer, the rule will match only if both the audience and the issuer match. |
+| `scopes` | _[JWTScope](#jwtscope) array_ | false | Scopes are a special type of claim in a JWT token that represents the permissions of the client.
The value of the scopes field should be a space delimited string that is expected in the scope parameter, as defined in RFC 6749: https://datatracker.ietf.org/doc/html/rfc6749#page-23.
If multiple scopes are specified, all scopes must match for the rule to match. |
+
+
#### JWTProvider
@@ -2128,6 +2430,17 @@ _Appears in:_
| `extractFrom` | _[JWTExtractor](#jwtextractor)_ | false | ExtractFrom defines different ways to extract the JWT token from HTTP request. If empty, it defaults to extract JWT token from the Authorization HTTP request header using Bearer schema or access_token from query parameters. |
+#### JWTScope
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [JWTPrincipal](#jwtprincipal)
+
+
+
#### KubernetesContainerSpec
@@ -2151,7 +2464,7 @@ _Appears in:_
-KubernetesDaemonsetSpec defines the desired state of the Kubernetes daemonset resource.
+KubernetesDaemonSetSpec defines the desired state of the Kubernetes daemonset resource.
_Appears in:_
- [EnvoyProxyKubernetesProvider](#envoyproxykubernetesprovider)
@@ -2216,17 +2529,22 @@ _Appears in:_
| `maxReplicas` | _integer_ | true | maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. It cannot be less that minReplicas. |
| `metrics` | _[MetricSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#metricspec-v2-autoscaling) array_ | false | metrics contains the specifications for which to use to calculate the desired replica count (the maximum replica count across all metrics will be used). If left empty, it defaults to being based on CPU utilization with average on 80% usage. |
| `behavior` | _[HorizontalPodAutoscalerBehavior](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#horizontalpodautoscalerbehavior-v2-autoscaling)_ | false | behavior configures the scaling behavior of the target in both Up and Down directions (scaleUp and scaleDown fields respectively). If not set, the default HPAScalingRules for scale up and scale down are used. See k8s.io.autoscaling.v2.HorizontalPodAutoScalerBehavior. |
+| `patch` | _[KubernetesPatchSpec](#kubernetespatchspec)_ | false | Patch defines how to perform the patch operation to the HorizontalPodAutoscaler |
#### KubernetesPatchSpec
-KubernetesPatchSpec defines how to perform the patch operation
+KubernetesPatchSpec defines how to perform the patch operation.
+Note that `value` can be an in-line YAML document, as can be seen in e.g. (the example of patching the Envoy proxy Deployment)[https://gateway.envoyproxy.io/docs/tasks/operations/customize-envoyproxy/#patching-deployment-for-envoyproxy].
+Note also that, currently, strings containing literal JSON are _rejected_.
_Appears in:_
- [KubernetesDaemonSetSpec](#kubernetesdaemonsetspec)
- [KubernetesDeploymentSpec](#kubernetesdeploymentspec)
+- [KubernetesHorizontalPodAutoscalerSpec](#kuberneteshorizontalpodautoscalerspec)
+- [KubernetesPodDisruptionBudgetSpec](#kubernetespoddisruptionbudgetspec)
- [KubernetesServiceSpec](#kubernetesservicespec)
| Field | Type | Required | Description |
@@ -2247,6 +2565,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `minAvailable` | _integer_ | false | MinAvailable specifies the minimum number of pods that must be available at all times during voluntary disruptions, such as node drains or updates. This setting ensures that your envoy proxy maintains a certain level of availability and resilience during maintenance operations. |
+| `patch` | _[KubernetesPatchSpec](#kubernetespatchspec)_ | false | Patch defines how to perform the patch operation to the PodDisruptionBudget |
#### KubernetesPodSpec
@@ -2284,6 +2603,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `annotations` | _object (keys:string, values:string)_ | false | Annotations that should be appended to the service. By default, no annotations are appended. |
+| `labels` | _object (keys:string, values:string)_ | false | Labels that should be appended to the service. By default, no labels are appended. |
| `type` | _[ServiceType](#servicetype)_ | false | Type determines how the Service is exposed. Defaults to LoadBalancer. Valid options are ClusterIP, LoadBalancer and NodePort. "LoadBalancer" means a service will be exposed via an external load balancer (if the cloud provider supports it). "ClusterIP" means a service will only be accessible inside the cluster, via the cluster IP. "NodePort" means a service will be exposed on a static Port on all Nodes of the cluster. |
| `loadBalancerClass` | _string_ | false | LoadBalancerClass, when specified, allows for choosing the LoadBalancer provider implementation if more than one are available or is otherwise expected to be specified |
| `allocateLoadBalancerNodePorts` | _boolean_ | false | AllocateLoadBalancerNodePorts defines if NodePorts will be automatically allocated for services with type LoadBalancer. Default is "true". It may be set to "false" if the cluster load-balancer does not rely on NodePorts. If the caller requests specific NodePorts (by specifying a value), those requests will be respected, regardless of this field. This field may only be set for services with type LoadBalancer and will be cleared if the type is changed to any other type. |
@@ -2360,6 +2680,7 @@ LoadBalancer defines the load balancer policy to be applied.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -2417,6 +2738,19 @@ _Appears in:_
| `error` | LogLevelError defines the "Error" logging level. |
+#### MergeType
+
+_Underlying type:_ _string_
+
+MergeType defines the type of merge operation
+
+_Appears in:_
+- [KubernetesPatchSpec](#kubernetespatchspec)
+
+| Value | Description |
+| ----- | ----------- |
+| `StrategicMerge` | StrategicMerge indicates a strategic merge patch type |
+| `JSONMerge` | JSONMerge indicates a JSON merge patch type |
#### MetricSinkType
@@ -2449,6 +2783,7 @@ _Appears in:_
| `clientID` | _string_ | true | The client ID to be used in the OIDC [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). |
| `clientSecret` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the OIDC client secret to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
This is an Opaque secret. The client secret should be stored in the key "client-secret". |
| `cookieNames` | _[OIDCCookieNames](#oidccookienames)_ | false | The optional cookie name overrides to be used for Bearer and IdToken cookies in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, uses a randomly generated suffix |
+| `cookieDomain` | _string_ | false | The optional domain to set the access and ID token cookies on. If not set, the cookies will default to the host of the request, not including the subdomains. If set, the cookies will be set on the specified domain and all subdomains. This means that requests to any subdomain will not require reauthentication after users log in to the parent domain. |
| `scopes` | _string array_ | false | The OIDC scopes to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). The "openid" scope is always added to the list of scopes if not already specified. |
| `resources` | _string array_ | false | The OIDC resources to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). |
| `redirectURL` | _string_ | true | The redirect URL to be used in the OIDC [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" |
@@ -2485,6 +2820,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `issuer` | _string_ | true | The OIDC Provider's [issuer identifier](https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery). Issuer MUST be a URI RFC 3986 [RFC3986] with a scheme component that MUST be https, a host component, and optionally, port and path components and no query or fragment components. |
| `authorizationEndpoint` | _string_ | false | The OIDC Provider's [authorization endpoint](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint). If not provided, EG will try to discover it from the provider's [Well-Known Configuration Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). |
| `tokenEndpoint` | _string_ | false | The OIDC Provider's [token endpoint](https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint). If not provided, EG will try to discover it from the provider's [Well-Known Configuration Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). |
@@ -2501,9 +2839,11 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `host` | _string_ | false | Host define the extension service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the extension service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the access log will be sent. Only Service kind is supported for now. |
| `resources` | _object (keys:string, values:string)_ | false | Resources is a set of labels that describe the source of a log entry, including envoy node info. It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). |
@@ -2623,17 +2963,15 @@ _Appears in:_
-Principal specifies the client identity of a request.
-A client identity can be a client IP, a JWT claim, username from the Authorization header,
-or any other identity that can be extracted from a custom header.
-Currently, only the client IP is supported.
+If there are multiple principal types, all principals must match for the rule to match.
_Appears in:_
- [AuthorizationRule](#authorizationrule)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `clientCIDRs` | _[CIDR](#cidr) array_ | true | ClientCIDRs are the IP CIDR ranges of the client. Valid examples are "192.168.1.0/24" or "2001:db8::/64"
The client IP is inferred from the X-Forwarded-For header, a custom header, or the proxy protocol. You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in the `ClientTrafficPolicy` to configure how the client IP is detected. |
+| `clientCIDRs` | _[CIDR](#cidr) array_ | false | ClientCIDRs are the IP CIDR ranges of the client. Valid examples are "192.168.1.0/24" or "2001:db8::/64"
If multiple CIDR ranges are specified, one of the CIDR ranges must match the client IP for the rule to match.
The client IP is inferred from the X-Forwarded-For header, a custom header, or the proxy protocol. You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in the `ClientTrafficPolicy` to configure how the client IP is detected. |
+| `jwt` | _[JWTPrincipal](#jwtprincipal)_ | false | JWT authorize the request based on the JWT claims and scopes. Note: in order to use JWT claims for authorization, you must configure the JWT authentication in the same `SecurityPolicy`. |
#### ProcessingModeOptions
@@ -2641,6 +2979,7 @@ _Appears in:_
ProcessingModeOptions defines if headers or body should be processed by the external service
+and which attributes are sent to the processor
_Appears in:_
- [ExtProcProcessingMode](#extprocprocessingmode)
@@ -2648,6 +2987,7 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `body` | _[ExtProcBodyProcessingMode](#extprocbodyprocessingmode)_ | false | Defines body processing mode |
+| `attributes` | _string array_ | false | Defines which attributes are sent to the external processor. Envoy Gateway currently supports only the following attribute prefixes: connection, source, destination, request, response, upstream and xds.route. https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/advanced/attributes |
#### ProviderType
@@ -2663,7 +3003,7 @@ _Appears in:_
| Value | Description |
| ----- | ----------- |
| `Kubernetes` | ProviderTypeKubernetes defines the "Kubernetes" provider. |
-| `File` | ProviderTypeFile defines the "File" provider. This type is not implemented until https://github.com/envoyproxy/gateway/issues/1001 is fixed. |
+| `Custom` | ProviderTypeCustom defines the "Custom" provider. |
#### ProxyAccessLog
@@ -2725,7 +3065,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `format` | _[ProxyAccessLogFormat](#proxyaccesslogformat)_ | false | Format defines the format of accesslog. This will be ignored if sink type is ALS. |
+| `matches` | _string array_ | true | Matches defines the match conditions for accesslog in CEL expression. An accesslog will be emitted only when one or more match conditions are evaluated to true. Invalid [CEL](https://www.envoyproxy.io/docs/envoy/latest/xds/type/v3/cel.proto.html#common-expression-language-cel-proto) expressions will be ignored. |
| `sinks` | _[ProxyAccessLogSink](#proxyaccesslogsink) array_ | true | Sinks defines the sinks of accesslog. |
+| `type` | _[ProxyAccessLogType](#proxyaccesslogtype)_ | false | Type defines the component emitting the accesslog, such as Listener and Route. If type not defined, the setting would apply to: (1) All Routes. (2) Listeners if and only if Envoy does not find a matching route for a request. If type is defined, the accesslog settings would apply to the relevant component (as-is). |
#### ProxyAccessLogSink
@@ -2761,6 +3103,21 @@ _Appears in:_
| `OpenTelemetry` | ProxyAccessLogSinkTypeOpenTelemetry defines the OpenTelemetry accesslog sink. When the provider is Kubernetes, EnvoyGateway always sends `k8s.namespace.name` and `k8s.pod.name` as additional attributes. |
+#### ProxyAccessLogType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [ProxyAccessLogSetting](#proxyaccesslogsetting)
+
+| Value | Description |
+| ----- | ----------- |
+| `Listener` | ProxyAccessLogTypeListener defines the accesslog for Listeners. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-access-log |
+| `Route` | ProxyAccessLogTypeRoute defines the accesslog for HTTP, GRPC, UDP and TCP Routes. https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/udp/udp_proxy/v3/udp_proxy.proto#envoy-v3-api-field-extensions-filters-udp-udp-proxy-v3-udpproxyconfig-access-log https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto#envoy-v3-api-field-extensions-filters-network-tcp-proxy-v3-tcpproxy-access-log https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-access-log |
+
+
#### ProxyBootstrap
@@ -2772,8 +3129,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `type` | _[BootstrapType](#bootstraptype)_ | false | Type is the type of the bootstrap configuration, it should be either Replace or Merge. If unspecified, it defaults to Replace. |
-| `value` | _string_ | true | Value is a YAML string of the bootstrap. |
+| `type` | _[BootstrapType](#bootstraptype)_ | false | Type is the type of the bootstrap configuration, it should be either Replace, Merge, or JSONPatch. If unspecified, it defaults to Replace. |
+| `value` | _string_ | false | Value is a YAML string of the bootstrap. |
+| `jsonPatches` | _[JSONPatchOperation](#jsonpatchoperation) array_ | true | JSONPatches is an array of JSONPatches to be applied to the default bootstrap. Patches are applied in the order in which they are defined. |
#### ProxyLogComponent
@@ -2843,8 +3201,9 @@ _Appears in:_
| `prometheus` | _[ProxyPrometheusProvider](#proxyprometheusprovider)_ | true | Prometheus defines the configuration for Admin endpoint `/stats/prometheus`. |
| `sinks` | _[ProxyMetricSink](#proxymetricsink) array_ | true | Sinks defines the metric sinks where metrics are sent to. |
| `matches` | _[StringMatch](#stringmatch) array_ | true | Matches defines configuration for selecting specific metrics instead of generating all metrics stats that are enabled by default. This helps reduce CPU and memory overhead in Envoy, but eliminating some stats may after critical functionality. Here are the stats that we strongly recommend not disabling: `cluster_manager.warming_clusters`, `cluster..membership_total`,`cluster..membership_healthy`, `cluster..membership_degraded`,reference https://github.com/envoyproxy/envoy/issues/9856, https://github.com/envoyproxy/envoy/issues/14610 |
-| `enableVirtualHostStats` | _boolean_ | true | EnableVirtualHostStats enables envoy stat metrics for virtual hosts. |
-| `enablePerEndpointStats` | _boolean_ | true | EnablePerEndpointStats enables per endpoint envoy stats metrics. Please use with caution. |
+| `enableVirtualHostStats` | _boolean_ | false | EnableVirtualHostStats enables envoy stat metrics for virtual hosts. |
+| `enablePerEndpointStats` | _boolean_ | false | EnablePerEndpointStats enables per endpoint envoy stats metrics. Please use with caution. |
+| `enableRequestResponseSizesStats` | _boolean_ | false | EnableRequestResponseSizesStats enables publishing of histograms tracking header and body sizes of requests and responses. |
#### ProxyOpenTelemetrySink
@@ -2858,9 +3217,11 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `host` | _string_ | false | Host define the service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the metric will be sent. Only Service kind is supported for now. |
#### ProxyPrometheusProvider
@@ -2887,6 +3248,7 @@ when communicating with the backend.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -3128,6 +3490,15 @@ _Appears in:_
| `url` | _string_ | true | URL is the endpoint of the trace collector that supports the OTLP protocol |
+#### RateLimitTracingProviderType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [RateLimitTracingProvider](#ratelimittracingprovider)
+
#### RateLimitType
@@ -3207,6 +3578,21 @@ _Appears in:_
| `uri` | _string_ | true | URI is the HTTPS URI to fetch the JWKS. Envoy's system trust bundle is used to validate the server certificate. |
+#### ReplaceRegexMatch
+
+
+
+
+
+_Appears in:_
+- [HTTPPathModifier](#httppathmodifier)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `pattern` | _string_ | true | Pattern matches a regular expression against the value of the HTTP Path.The regex string must adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax. |
+| `substitution` | _string_ | true | Substitution is an expression that replaces the matched portion.The expression may include numbered capture groups that adhere to syntax documented in https://github.com/google/re2/wiki/Syntax. |
+
+
#### RequestHeaderCustomTag
@@ -3236,6 +3622,36 @@ _Appears in:_
| `File` | ResourceProviderTypeFile defines the "File" provider. |
+#### ResponseOverride
+
+
+
+ResponseOverride defines the configuration to override specific responses with a custom one.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `match` | _[CustomResponseMatch](#customresponsematch)_ | true | Match configuration. |
+| `response` | _[CustomResponse](#customresponse)_ | true | Response configuration. |
+
+
+#### ResponseValueType
+
+_Underlying type:_ _string_
+
+ResponseValueType defines the types of values for the response body supported by Envoy Gateway.
+
+_Appears in:_
+- [CustomResponseBody](#customresponsebody)
+
+| Value | Description |
+| ----- | ----------- |
+| `Inline` | ResponseValueTypeInline defines the "Inline" response body type. |
+| `ValueRef` | ResponseValueTypeValueRef defines the "ValueRef" response body type. |
+
+
#### Retry
@@ -3244,6 +3660,7 @@ Retry defines the retry strategy to be applied.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -3289,8 +3706,7 @@ _Appears in:_
SecurityPolicy allows the user to configure various security settings for a
Gateway.
-_Appears in:_
-- [SecurityPolicyList](#securitypolicylist)
+
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -3301,22 +3717,6 @@ _Appears in:_
| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of SecurityPolicy. |
-#### SecurityPolicyList
-
-
-
-SecurityPolicyList contains a list of SecurityPolicy resources.
-
-
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
-| `kind` | _string_ | |`SecurityPolicyList`
-| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
-| `items` | _[SecurityPolicy](#securitypolicy) array_ | true | |
-
-
#### SecurityPolicySpec
@@ -3372,6 +3772,35 @@ _Appears in:_
| `NodePort` | ServiceTypeNodePort means a service will be exposed on each Kubernetes Node at a static Port, common across all Nodes. |
+#### Session
+
+
+
+Session defines settings related to TLS session management.
+
+_Appears in:_
+- [ClientTLSSettings](#clienttlssettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `resumption` | _[SessionResumption](#sessionresumption)_ | false | Resumption determines the proxy's supported TLS session resumption option. By default, Envoy Gateway does not enable session resumption. Use sessionResumption to enable stateful and stateless session resumption. Users should consider security impacts of different resumption methods. Performance gains from resumption are diminished when Envoy proxy is deployed with more than one replica. |
+
+
+#### SessionResumption
+
+
+
+SessionResumption defines supported tls session resumption methods and their associated configuration.
+
+_Appears in:_
+- [Session](#session)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `stateless` | _[StatelessTLSSessionResumption](#statelesstlssessionresumption)_ | false | Stateless defines setting for stateless (session-ticket based) session resumption |
+| `stateful` | _[StatefulTLSSessionResumption](#statefultlssessionresumption)_ | false | Stateful defines setting for stateful (session-id based) session resumption |
+
+
#### ShutdownConfig
@@ -3383,8 +3812,8 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `drainTimeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds. If unspecified, defaults to 600 seconds. |
-| `minDrainDuration` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete. If unspecified, defaults to 5 seconds. |
+| `drainTimeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds. If unspecified, defaults to 60 seconds. |
+| `minDrainDuration` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete. If unspecified, defaults to 10 seconds. |
#### ShutdownManager
@@ -3415,6 +3844,19 @@ _Appears in:_
| `window` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | Window defines the duration of the warm up period for newly added host. During slow start window, traffic sent to the newly added hosts will gradually increase. Currently only supports linear growth of traffic. For additional details, see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig |
+#### SourceMatch
+
+
+
+
+
+_Appears in:_
+- [RateLimitSelectCondition](#ratelimitselectcondition)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[SourceMatchType](#sourcematchtype)_ | false | |
+| `value` | _string_ | true | Value is the IP CIDR that represents the range of Source IP Addresses of the client. These could also be the intermediate addresses through which the request has flown through and is part of the `X-Forwarded-For` header. For example, `192.168.0.1/32`, `192.168.0.0/24`, `001:db8::/64`. |
#### SourceMatchType
@@ -3432,6 +3874,83 @@ _Appears in:_
| `Distinct` | SourceMatchDistinct Each IP Address within the specified Source IP CIDR is treated as a distinct client selector and uses a separate rate limit bucket/counter. Note: This is only supported for Global Rate Limits. |
+#### StatefulTLSSessionResumption
+
+
+
+StatefulTLSSessionResumption defines the stateful (session-id based) type of TLS session resumption.
+Note: When Envoy Proxy is deployed with more than one replica, session caches are not synchronized
+between instances, possibly leading to resumption failures.
+Envoy does not re-validate client certificates upon session resumption.
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-routematch-tlscontextmatchoptions
+
+_Appears in:_
+- [SessionResumption](#sessionresumption)
+
+
+
+#### StatelessTLSSessionResumption
+
+
+
+StatelessTLSSessionResumption defines the stateless (session-ticket based) type of TLS session resumption.
+Note: When Envoy Proxy is deployed with more than one replica, session ticket encryption keys are not
+synchronized between instances, possibly leading to resumption failures.
+In-memory session ticket encryption keys are rotated every 48 hours.
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#extensions-transport-sockets-tls-v3-tlssessionticketkeys
+https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#Session-tickets
+
+_Appears in:_
+- [SessionResumption](#sessionresumption)
+
+
+
+#### StatusCodeMatch
+
+
+
+StatusCodeMatch defines the configuration for matching a status code.
+
+_Appears in:_
+- [CustomResponseMatch](#customresponsematch)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[StatusCodeValueType](#statuscodevaluetype)_ | true | Type is the type of value. Valid values are Value and Range, default is Value. |
+| `value` | _integer_ | false | Value contains the value of the status code. |
+| `range` | _[StatusCodeRange](#statuscoderange)_ | false | Range contains the range of status codes. |
+
+
+#### StatusCodeRange
+
+
+
+StatusCodeRange defines the configuration for define a range of status codes.
+
+_Appears in:_
+- [StatusCodeMatch](#statuscodematch)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `start` | _integer_ | true | Start of the range, including the start value. |
+| `end` | _integer_ | true | End of the range, including the end value. |
+
+
+#### StatusCodeValueType
+
+_Underlying type:_ _string_
+
+StatusCodeValueType defines the types of values for the status code match supported by Envoy Gateway.
+
+_Appears in:_
+- [StatusCodeMatch](#statuscodematch)
+
+| Value | Description |
+| ----- | ----------- |
+| `Value` | StatusCodeValueTypeValue defines the "Value" status code match type. |
+| `Range` | StatusCodeValueTypeRange defines the "Range" status code match type. |
+
+
#### StringMatch
@@ -3505,6 +4024,7 @@ TCPKeepalive define the TCP Keepalive configuration.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -3544,7 +4064,7 @@ _Appears in:_
| `ciphers` | _string array_ | false | Ciphers specifies the set of cipher suites supported when negotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3. In non-FIPS Envoy Proxy builds the default cipher list is: - [ECDHE-ECDSA-AES128-GCM-SHA256\|ECDHE-ECDSA-CHACHA20-POLY1305] - [ECDHE-RSA-AES128-GCM-SHA256\|ECDHE-RSA-CHACHA20-POLY1305] - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 In builds using BoringSSL FIPS the default cipher list is: - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 |
| `ecdhCurves` | _string array_ | false | ECDHCurves specifies the set of supported ECDH curves. In non-FIPS Envoy Proxy builds the default curves are: - X25519 - P-256 In builds using BoringSSL FIPS the default curve is: - P-256 |
| `signatureAlgorithms` | _string array_ | false | SignatureAlgorithms specifies which signature algorithms the listener should support. |
-| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be exposed by the listener. By default h2 and http/1.1 are enabled. Supported values are: - http/1.0 - http/1.1 - h2 |
+| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be exposed by the listener or used by the proxy to connect to the backend. Defaults: 1. HTTPS Routes: h2 and http/1.1 are enabled in listener context. 2. Other Routes: ALPN is disabled. 3. Backends: proxy uses the appropriate ALPN options for the backend protocol. When an empty list is provided, the ALPN TLS extension is disabled. Supported values are: - http/1.0 - http/1.1 - h2 |
#### TLSVersion
@@ -3595,6 +4115,7 @@ Timeout defines configuration for timeouts related to connections.
_Appears in:_
- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
@@ -3613,10 +4134,12 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `type` | _[TracingProviderType](#tracingprovidertype)_ | true | Type defines the tracing provider type. |
| `host` | _string_ | false | Host define the provider service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the provider service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the trace will be sent. Only Service kind is supported for now. |
| `zipkin` | _[ZipkinTracingProvider](#zipkintracingprovider)_ | false | Zipkin defines the Zipkin tracing provider configuration |
@@ -3634,6 +4157,7 @@ _Appears in:_
| `OpenTelemetry` | |
| `OpenTelemetry` | |
| `Zipkin` | |
+| `Datadog` | |
#### TriggerEnum
@@ -3697,6 +4221,7 @@ _Appears in:_
| `code` | _[WasmCodeSource](#wasmcodesource)_ | true | Code is the Wasm code for the extension. |
| `config` | _[JSON](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#json-v1-apiextensions-k8s-io)_ | false | Config is the configuration for the Wasm extension. This configuration will be passed as a JSON string to the Wasm extension. |
| `failOpen` | _boolean_ | false | FailOpen is a switch used to control the behavior when a fatal error occurs during the initialization or the execution of the Wasm extension. If FailOpen is set to true, the system bypasses the Wasm extension and allows the traffic to pass through. Otherwise, if it is set to false or not set (defaulting to false), the system blocks the traffic and returns an HTTP 5xx error. |
+| `env` | _[WasmEnv](#wasmenv)_ | false | Env configures the environment for the Wasm extension |
#### WasmCodeSource
@@ -3731,6 +4256,20 @@ _Appears in:_
| `Image` | ImageWasmCodeSourceType allows the user to specify the Wasm code in an OCI image. |
+#### WasmEnv
+
+
+
+WasmEnv defines the environment variables for the VM of a Wasm extension
+
+_Appears in:_
+- [Wasm](#wasm)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `hostKeys` | _string array_ | false | HostKeys is a list of keys for environment variables from the host envoy process that should be passed into the Wasm VM. This is useful for passing secrets to to Wasm extensions. |
+
+
#### WithUnderscoresAction
_Underlying type:_ _string_
@@ -3837,13 +4376,15 @@ _Appears in:_
XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address.
+Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
+for more details.
_Appears in:_
- [ClientIPDetectionSettings](#clientipdetectionsettings)
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `numTrustedHops` | _integer_ | false | NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP headers to trust when determining the origin client's IP address. Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for for more details. |
+| `numTrustedHops` | _integer_ | false | NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP headers to trust when determining the origin client's IP address. Only one of NumTrustedHops and TrustedCIDRs must be set. |
#### ZipkinTracingProvider
diff --git a/site/content/en/latest/boilerplates/rollout-envoy-gateway.md b/site/content/en/latest/boilerplates/rollout-envoy-gateway.md
new file mode 100644
index 00000000000..9072526868c
--- /dev/null
+++ b/site/content/en/latest/boilerplates/rollout-envoy-gateway.md
@@ -0,0 +1,10 @@
+---
+---
+
+> After updating the `ConfigMap`, you will need to wait the configuration kicks in.
+> You can **force** the configuration to be reloaded by restarting the `envoy-gateway` deployment.
+>
+> ```shell
+> kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
+> ```
+>
\ No newline at end of file
diff --git a/site/content/en/latest/concepts/concepts_overview.md b/site/content/en/latest/concepts/concepts_overview.md
index 31838b520f2..6f37f87f283 100644
--- a/site/content/en/latest/concepts/concepts_overview.md
+++ b/site/content/en/latest/concepts/concepts_overview.md
@@ -10,13 +10,12 @@ There are several resources that play a part in enabling you to meet your Kubern
There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
-# Overview
-
-## Kubernetes Gateway API Resources
+### Kubernetes Gateway API Resources
- **GatewayClass:** Defines a class of Gateways with common configuration.
- **Gateway:** Specifies how traffic can enter the cluster.
- **Routes:** **HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute:** Define routing rules for different types of traffic.
-## Envoy Gateway (EG) API Resources
+
+### Envoy Gateway (EG) API Resources
- **EnvoyProxy:** Represents the deployment and configuration of the Envoy proxy within a Kubernetes cluster, managing its lifecycle and settings.
- **EnvoyPatchPolicy, ClientTrafficPolicy, SecurityPolicy, BackendTrafficPolicy, EnvoyExtensionPolicy, BackendTLSPolicy:** Additional policies and configurations specific to Envoy Gateway.
- **Backend:** A resource that makes routing to cluster-external backends easier and makes access to external processes via Unix Domain Sockets possible.
@@ -28,12 +27,14 @@ There are several resources that play a part in enabling you to meet your Kubern
| [HTTPRoute][3] [GRPCRoute][4] [TLSRoute][5] [TCPRoute][6] [UDPRoute][7] | Gateway API | Yes | Routing | Gateway | Define routing rules for different types of traffic. **Note:**_For simplicity these resources are referenced collectively as Route in the References column_ |
| [Backend][8] | EG API | No | Routing | N/A | Used for routing to cluster-external backends using FQDN or IP. Can also be used when you want to extend Envoy with external processes accessed via Unix Domain Sockets. |
| [ClientTrafficPolicy][9] | EG API | No | Traffic Handling | Gateway | Specifies policies for handling client traffic, including rate limiting, retries, and other client-specific configurations. |
-| [BackendTrafficPolicy][10] | EG API | No | Traffic Handling | Gateway Route | Specifies policies for traffic directed towards backend services, including load balancing, health checks, and failover strategies. **Note:**_Most specific configuration wins_ |
-| [SecurityPolicy][11] | EG API | No | Security | Gateway Route | Defines security-related policies such as authentication, authorization, and encryption settings for traffic handled by Envoy Gateway. **Note:**_Most specific configuration wins_ |
+| [BackendTrafficPolicy][10] | EG API | No | Traffic Handling | Gateway, Route | Specifies policies for traffic directed towards backend services, including load balancing, health checks, and failover strategies. **Note:**_Most specific configuration wins_ |
+| [SecurityPolicy][11] | EG API | No | Security | Gateway, Route | Defines security-related policies such as authentication, authorization, and encryption settings for traffic handled by Envoy Gateway. **Note:**_Most specific configuration wins_ |
| [BackendTLSPolicy][12] | Gateway API | No | Security | Service | Defines TLS settings for backend connections, including certificate management, TLS version settings, and other security configurations. This policy is applied to Kubernetes Services. |
-| [EnvoyProxy][13] | EG API | No | Customize & Extend | GatewayClass Gateway | The EnvoyProxy resource represents the deployment and configuration of the Envoy proxy itself within a Kubernetes cluster, managing its lifecycle and settings. **Note:**_Most specific configuration wins_ |
-| [EnvoyPatchPolicy][14] | EG API | No | Customize & Extend | GatewayClass Gateway | This policy defines custom patches to be applied to Envoy Gateway resources, allowing users to tailor the configuration to their specific needs. **Note:**_Most specific configuration wins_ |
-| [EnvoyExtensionPolicy][15] | EG API | No | Customize & Extend | Gateway Route, Backend | Allows for the configuration of Envoy proxy extensions, enabling custom behavior and functionality. **Note:**_Most specific configuration wins_ |
+| [EnvoyProxy][13] | EG API | No | Customize & Extend | GatewayClass, Gateway | The EnvoyProxy resource represents the deployment and configuration of the Envoy proxy itself within a Kubernetes cluster, managing its lifecycle and settings. **Note:**_Most specific configuration wins_ |
+| [EnvoyPatchPolicy][14] | EG API | No | Customize & Extend | GatewayClass, Gateway | This policy defines custom patches to be applied to Envoy Gateway resources, allowing users to tailor the configuration to their specific needs. **Note:**_Most specific configuration wins_ |
+| [EnvoyExtensionPolicy][15] | EG API | No | Customize & Extend | Gateway, Route, Backend| Allows for the configuration of Envoy proxy extensions, enabling custom behavior and functionality. **Note:**_Most specific configuration wins_ |
+| [HTTPRouteFilter][16] | EG API | No | Customize & Extend | HTTPRoute | Allows for the additional request/response processing. |
+
@@ -51,4 +52,5 @@ There are several resources that play a part in enabling you to meet your Kubern
[12]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
[13]: ../api/extension_types#envoyproxy
[14]: ../api/extension_types#envoypatchpolicy
-[15]: ../api/extension_types#envoyextensionpolicy
\ No newline at end of file
+[15]: ../api/extension_types#envoyextensionpolicy
+[16]: ../api/extension_types#httproutefilter
diff --git a/site/content/en/latest/install/gateway-addons-helm-api.md b/site/content/en/latest/install/gateway-addons-helm-api.md
index 448aa91e504..dce51039fa2 100644
--- a/site/content/en/latest/install/gateway-addons-helm-api.md
+++ b/site/content/en/latest/install/gateway-addons-helm-api.md
@@ -24,16 +24,20 @@ An Add-ons Helm chart for Envoy Gateway
| Repository | Name | Version |
|------------|------|---------|
| https://fluent.github.io/helm-charts | fluent-bit | 0.30.4 |
+| https://grafana.github.io/helm-charts | alloy | 0.9.2 |
| https://grafana.github.io/helm-charts | grafana | 8.0.0 |
| https://grafana.github.io/helm-charts | loki | 4.8.0 |
| https://grafana.github.io/helm-charts | tempo | 1.3.1 |
-| https://open-telemetry.github.io/opentelemetry-helm-charts | opentelemetry-collector | 0.73.1 |
+| https://open-telemetry.github.io/opentelemetry-helm-charts | opentelemetry-collector | 0.108.0 |
| https://prometheus-community.github.io/helm-charts | prometheus | 25.21.0 |
## Values
| Key | Type | Default | Description |
|-----|------|---------|-------------|
+| alloy.alloy.configMap.content | string | `"// Write your Alloy config here:\nlogging {\n level = \"info\"\n format = \"logfmt\"\n}\nloki.write \"alloy\" {\n endpoint {\n url = \"http://loki.monitoring.svc:3100/loki/api/v1/push\"\n }\n}\n// discovery.kubernetes allows you to find scrape targets from Kubernetes resources.\n// It watches cluster state and ensures targets are continually synced with what is currently running in your cluster.\ndiscovery.kubernetes \"pod\" {\n role = \"pod\"\n}\n\n// discovery.relabel rewrites the label set of the input targets by applying one or more relabeling rules.\n// If no rules are defined, then the input targets are exported as-is.\ndiscovery.relabel \"pod_logs\" {\n targets = discovery.kubernetes.pod.targets\n\n // Label creation - \"namespace\" field from \"__meta_kubernetes_namespace\"\n rule {\n source_labels = [\"__meta_kubernetes_namespace\"]\n action = \"replace\"\n target_label = \"namespace\"\n }\n\n // Label creation - \"pod\" field from \"__meta_kubernetes_pod_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_name\"]\n action = \"replace\"\n target_label = \"pod\"\n }\n\n // Label creation - \"container\" field from \"__meta_kubernetes_pod_container_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"container\"\n }\n\n // Label creation - \"app\" field from \"__meta_kubernetes_pod_label_app_kubernetes_io_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_label_app_kubernetes_io_name\"]\n action = \"replace\"\n target_label = \"app\"\n }\n\n // Label creation - \"job\" field from \"__meta_kubernetes_namespace\" and \"__meta_kubernetes_pod_container_name\"\n // Concatenate values __meta_kubernetes_namespace/__meta_kubernetes_pod_container_name\n rule {\n source_labels = [\"__meta_kubernetes_namespace\", \"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"job\"\n separator = \"/\"\n replacement = \"$1\"\n }\n\n // Label creation - \"container\" field from \"__meta_kubernetes_pod_uid\" and \"__meta_kubernetes_pod_container_name\"\n // Concatenate values __meta_kubernetes_pod_uid/__meta_kubernetes_pod_container_name.log\n rule {\n source_labels = [\"__meta_kubernetes_pod_uid\", \"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"__path__\"\n separator = \"/\"\n replacement = \"/var/log/pods/*$1/*.log\"\n }\n\n // Label creation - \"container_runtime\" field from \"__meta_kubernetes_pod_container_id\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_container_id\"]\n action = \"replace\"\n target_label = \"container_runtime\"\n regex = \"^(\\\\S+):\\\\/\\\\/.+$\"\n replacement = \"$1\"\n }\n}\n\n// loki.source.kubernetes tails logs from Kubernetes containers using the Kubernetes API.\nloki.source.kubernetes \"pod_logs\" {\n targets = discovery.relabel.pod_logs.output\n forward_to = [loki.process.pod_logs.receiver]\n}\n// loki.process receives log entries from other Loki components, applies one or more processing stages,\n// and forwards the results to the list of receivers in the component’s arguments.\nloki.process \"pod_logs\" {\n stage.static_labels {\n values = {\n cluster = \"envoy-gateway\",\n }\n }\n\n forward_to = [loki.write.alloy.receiver]\n}"` | |
+| alloy.enabled | bool | `false` | |
+| alloy.fullnameOverride | string | `"alloy"` | |
| fluent-bit.config.filters | string | `"[FILTER]\n Name kubernetes\n Match kube.*\n Merge_Log On\n Keep_Log Off\n K8S-Logging.Parser On\n K8S-Logging.Exclude On\n\n[FILTER]\n Name grep\n Match kube.*\n Regex $kubernetes['container_name'] ^envoy$\n\n[FILTER]\n Name parser\n Match kube.*\n Key_Name log\n Parser envoy\n Reserve_Data True\n"` | |
| fluent-bit.config.inputs | string | `"[INPUT]\n Name tail\n Path /var/log/containers/*.log\n multiline.parser docker, cri\n Tag kube.*\n Mem_Buf_Limit 5MB\n Skip_Long_Lines On\n"` | |
| fluent-bit.config.outputs | string | `"[OUTPUT]\n Name loki\n Match kube.*\n Host loki.monitoring.svc.cluster.local\n Port 3100\n Labels job=fluentbit, app=$kubernetes['labels']['app'], k8s_namespace_name=$kubernetes['namespace_name'], k8s_pod_name=$kubernetes['pod_name'], k8s_container_name=$kubernetes['container_name']\n"` | |
@@ -63,6 +67,7 @@ An Add-ons Helm chart for Envoy Gateway
| grafana.enabled | bool | `true` | |
| grafana.fullnameOverride | string | `"grafana"` | |
| grafana.service.type | string | `"LoadBalancer"` | |
+| grafana.testFramework.enabled | bool | `false` | |
| loki.backend.replicas | int | `0` | |
| loki.deploymentMode | string | `"SingleBinary"` | |
| loki.enabled | bool | `true` | |
@@ -81,29 +86,40 @@ An Add-ons Helm chart for Envoy Gateway
| loki.singleBinary.replicas | int | `1` | |
| loki.test.enabled | bool | `false` | |
| loki.write.replicas | int | `0` | |
-| opentelemetry-collector.config.exporters.logging.verbosity | string | `"detailed"` | |
+| opentelemetry-collector.config.exporters.debug.verbosity | string | `"detailed"` | |
| opentelemetry-collector.config.exporters.loki.endpoint | string | `"http://loki.monitoring.svc:3100/loki/api/v1/push"` | |
| opentelemetry-collector.config.exporters.otlp.endpoint | string | `"tempo.monitoring.svc:4317"` | |
| opentelemetry-collector.config.exporters.otlp.tls.insecure | bool | `true` | |
-| opentelemetry-collector.config.exporters.prometheus.endpoint | string | `"0.0.0.0:19001"` | |
-| opentelemetry-collector.config.extensions.health_check | object | `{}` | |
+| opentelemetry-collector.config.exporters.prometheus.endpoint | string | `"[${env:MY_POD_IP}]:19001"` | |
+| opentelemetry-collector.config.extensions.health_check.endpoint | string | `"[${env:MY_POD_IP}]:13133"` | |
| opentelemetry-collector.config.processors.attributes.actions[0].action | string | `"insert"` | |
| opentelemetry-collector.config.processors.attributes.actions[0].key | string | `"loki.attribute.labels"` | |
| opentelemetry-collector.config.processors.attributes.actions[0].value | string | `"k8s.pod.name, k8s.namespace.name"` | |
-| opentelemetry-collector.config.receivers.otlp.protocols.grpc.endpoint | string | `"${env:MY_POD_IP}:4317"` | |
-| opentelemetry-collector.config.receivers.otlp.protocols.http.endpoint | string | `"${env:MY_POD_IP}:4318"` | |
-| opentelemetry-collector.config.receivers.zipkin.endpoint | string | `"${env:MY_POD_IP}:9411"` | |
+| opentelemetry-collector.config.receivers.datadog.endpoint | string | `"[${env:MY_POD_IP}]:8126"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.grpc.endpoint | string | `"[${env:MY_POD_IP}]:14250"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.thrift_compact.endpoint | string | `"[${env:MY_POD_IP}]:6831"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.thrift_http.endpoint | string | `"[${env:MY_POD_IP}]:14268"` | |
+| opentelemetry-collector.config.receivers.otlp.protocols.grpc.endpoint | string | `"[${env:MY_POD_IP}]:4317"` | |
+| opentelemetry-collector.config.receivers.otlp.protocols.http.endpoint | string | `"[${env:MY_POD_IP}]:4318"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].job_name | string | `"opentelemetry-collector"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].scrape_interval | string | `"10s"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].static_configs[0].targets[0] | string | `"[${env:MY_POD_IP}]:8888"` | |
+| opentelemetry-collector.config.receivers.zipkin.endpoint | string | `"[${env:MY_POD_IP}]:9411"` | |
| opentelemetry-collector.config.service.extensions[0] | string | `"health_check"` | |
| opentelemetry-collector.config.service.pipelines.logs.exporters[0] | string | `"loki"` | |
| opentelemetry-collector.config.service.pipelines.logs.processors[0] | string | `"attributes"` | |
| opentelemetry-collector.config.service.pipelines.logs.receivers[0] | string | `"otlp"` | |
| opentelemetry-collector.config.service.pipelines.metrics.exporters[0] | string | `"prometheus"` | |
-| opentelemetry-collector.config.service.pipelines.metrics.receivers[0] | string | `"otlp"` | |
+| opentelemetry-collector.config.service.pipelines.metrics.receivers[0] | string | `"datadog"` | |
+| opentelemetry-collector.config.service.pipelines.metrics.receivers[1] | string | `"otlp"` | |
| opentelemetry-collector.config.service.pipelines.traces.exporters[0] | string | `"otlp"` | |
-| opentelemetry-collector.config.service.pipelines.traces.receivers[0] | string | `"otlp"` | |
-| opentelemetry-collector.config.service.pipelines.traces.receivers[1] | string | `"zipkin"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[0] | string | `"datadog"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[1] | string | `"otlp"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[2] | string | `"zipkin"` | |
+| opentelemetry-collector.config.service.telemetry.metrics.address | string | `"[${env:MY_POD_IP}]:8888"` | |
| opentelemetry-collector.enabled | bool | `false` | |
| opentelemetry-collector.fullnameOverride | string | `"otel-collector"` | |
+| opentelemetry-collector.image.repository | string | `"otel/opentelemetry-collector-contrib"` | |
| opentelemetry-collector.mode | string | `"deployment"` | |
| prometheus.alertmanager.enabled | bool | `false` | |
| prometheus.enabled | bool | `true` | |
diff --git a/site/content/en/latest/install/gateway-helm-api.md b/site/content/en/latest/install/gateway-helm-api.md
index 9f2046a537f..bb817b992dc 100644
--- a/site/content/en/latest/install/gateway-helm-api.md
+++ b/site/content/en/latest/install/gateway-helm-api.md
@@ -23,7 +23,7 @@ The Helm chart for Envoy Gateway
| Key | Type | Default | Description |
|-----|------|---------|-------------|
-| certgen | object | `{"job":{"annotations":{},"resources":{},"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
+| certgen | object | `{"job":{"affinity":{},"annotations":{},"nodeSelector":{},"resources":{},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsGroup":65534,"runAsNonRoot":true,"runAsUser":65534,"seccompProfile":{"type":"RuntimeDefault"}},"tolerations":[],"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
| config.envoyGateway.gateway.controllerName | string | `"gateway.envoyproxy.io/gatewayclass-controller"` | |
| config.envoyGateway.logging.level.default | string | `"info"` | |
| config.envoyGateway.provider.type | string | `"Kubernetes"` | |
@@ -32,14 +32,21 @@ The Helm chart for Envoy Gateway
| deployment.envoyGateway.image.tag | string | `""` | |
| deployment.envoyGateway.imagePullPolicy | string | `""` | |
| deployment.envoyGateway.imagePullSecrets | list | `[]` | |
-| deployment.envoyGateway.resources.limits.cpu | string | `"500m"` | |
| deployment.envoyGateway.resources.limits.memory | string | `"1024Mi"` | |
| deployment.envoyGateway.resources.requests.cpu | string | `"100m"` | |
| deployment.envoyGateway.resources.requests.memory | string | `"256Mi"` | |
+| deployment.envoyGateway.securityContext.allowPrivilegeEscalation | bool | `false` | |
+| deployment.envoyGateway.securityContext.capabilities.drop[0] | string | `"ALL"` | |
+| deployment.envoyGateway.securityContext.privileged | bool | `false` | |
+| deployment.envoyGateway.securityContext.runAsGroup | int | `65532` | |
+| deployment.envoyGateway.securityContext.runAsNonRoot | bool | `true` | |
+| deployment.envoyGateway.securityContext.runAsUser | int | `65532` | |
+| deployment.envoyGateway.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | |
| deployment.pod.affinity | object | `{}` | |
| deployment.pod.annotations."prometheus.io/port" | string | `"19001"` | |
| deployment.pod.annotations."prometheus.io/scrape" | string | `"true"` | |
| deployment.pod.labels | object | `{}` | |
+| deployment.pod.nodeSelector | object | `{}` | |
| deployment.pod.tolerations | list | `[]` | |
| deployment.pod.topologySpreadConstraints | list | `[]` | |
| deployment.ports[0].name | string | `"grpc"` | |
@@ -54,6 +61,7 @@ The Helm chart for Envoy Gateway
| deployment.ports[3].name | string | `"metrics"` | |
| deployment.ports[3].port | int | `19001` | |
| deployment.ports[3].targetPort | int | `19001` | |
+| deployment.priorityClassName | string | `nil` | |
| deployment.replicas | int | `1` | |
| global.images.envoyGateway.image | string | `nil` | |
| global.images.envoyGateway.pullPolicy | string | `nil` | |
@@ -63,4 +71,5 @@ The Helm chart for Envoy Gateway
| global.images.ratelimit.pullSecrets | list | `[]` | |
| kubernetesClusterDomain | string | `"cluster.local"` | |
| podDisruptionBudget.minAvailable | int | `0` | |
+| service.annotations | object | `{}` | |
diff --git a/site/content/en/latest/install/install-helm.md b/site/content/en/latest/install/install-helm.md
index 277856b9aac..16975efc84d 100644
--- a/site/content/en/latest/install/install-helm.md
+++ b/site/content/en/latest/install/install-helm.md
@@ -59,6 +59,12 @@ consideration when debugging.
[`quickstart.yaml`]: https://github.com/envoyproxy/gateway/releases/download/{{< yaml-version >}}/quickstart.yaml
+## Upgrading from a previous version
+
+[Helm](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations) does not update CRDs
+that live in the `/crds` folder in the Helm Chart. So you will manually need to update the CRDs.
+Follow the steps outlined in [this](./install-yaml/#upgrading-from-v1.1) section if you're upgrading from a previous version.
+
## Helm chart customizations
Some of the quick ways of using the helm install command for envoy gateway installation are below.
diff --git a/site/content/en/latest/install/install-yaml.md b/site/content/en/latest/install/install-yaml.md
index e675f15fbec..0da5ca9cca1 100644
--- a/site/content/en/latest/install/install-yaml.md
+++ b/site/content/en/latest/install/install-yaml.md
@@ -13,7 +13,7 @@ installation, it is recommended that you use helm.
Envoy Gateway is designed to run in Kubernetes for production. The most essential requirements are:
-* Kubernetes 1.25 or later
+* Kubernetes 1.28 or later
* The `kubectl` command-line tool
{{% alert title="Compatibility Matrix" color="warning" %}}
@@ -37,3 +37,24 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more.
2. Next Steps
Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks).
+
+## Upgrading from v1.1
+
+Some manual migration steps are required to upgrade Envoy Gateway to v1.2.
+
+1. Update your `GRPCRoute` and `ReferenceGrant` resources if the storage version being used is `v1alpha2`.
+Follow the steps in Gateway-API [v1.2 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v12-upgrade-notes)
+
+2. Update Gateway-API and Envoy Gateway CRDs:
+
+```shell
+helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-crds.yaml
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated
+```
+
+3. Install Envoy Gateway {{< yaml-version >}}:
+
+```shell
+helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system
+```
diff --git a/site/content/en/latest/install/migrating-to-envoy.md b/site/content/en/latest/install/migrating-to-envoy.md
new file mode 100644
index 00000000000..470c759ab7e
--- /dev/null
+++ b/site/content/en/latest/install/migrating-to-envoy.md
@@ -0,0 +1,143 @@
+---
+title: Migrating from Ingress Resources
+---
+
+## Introduction
+
+Migrating from Ingress to Envoy Gateway involves converting existing Ingress resources into resources compatible with Envoy Gateway. The `ingress2gateway` tool simplifies this migration by transforming Ingress resources into Gateway API resources that Envoy Gateway can use. This guide will walk you through the prerequisites, installation of the `ingress2gateway` tool, and provide an example migration process.
+
+## Prerequisites
+
+Before you start the migration, ensure you have the following:
+
+1. **Envoy Gateway Installed**: You need Envoy Gateway set up in your Kubernetes cluster. Follow the [Envoy Gateway installation guide](../install) for details.
+2. **Kubernetes Cluster Access**: Ensure you have access to your Kubernetes cluster and necessary permissions to manage resources.
+3. **Installation of `ingress2gateway` Tool**: You need to install the `ingress2gateway` tool in your Kubernetes cluster and configure it accordingly. Follow the [ingress2gateway tool installation guide](https://github.com/kubernetes-sigs/ingress2gateway/blob/main/README.md#installation) for details.
+
+## Example Migration
+
+Here’s a step-by-step example of migrating from Ingress to Envoy Gateway using `ingress2gateway`:
+
+### 1. Install and Configure Envoy Gateway
+
+Ensure that Envoy Gateway is installed and running in your cluster. Follow the [official Envoy Gateway installation guide](../install) for setup instructions.
+
+### 2. Create a GatewayClass
+
+To ensure the generated HTTPRoutes are programmed correctly in the Envoy Gateway data plane, create a GatewayClass that links to the Envoy Gateway controller.
+
+Create a `GatewayClass` resource:
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: GatewayClass
+metadata:
+ name: envoy-gateway-class
+spec:
+ controllerName: gateway.envoyproxy.io/controller
+```
+
+Apply this resource:
+
+```sh
+kubectl apply -f gatewayclass.yaml
+```
+
+### 3. Install Ingress2gateway
+
+Ensure you have the Ingress2gateway package installed. If not, follow the package’s installation instructions.
+
+### 4. Run Ingress2gateway
+
+Use Ingress2gateway to read your existing Ingress resources and translate them into Gateway API resources.
+
+```sh
+./ingress2gateway print
+```
+
+This command will:
+1. Read your Kube config file to extract the cluster credentials and the current active namespace.
+2. Search for Ingress and provider-specific resources in that namespace.
+3. Convert them to Gateway API resources (Gateways and HTTPRoutes).
+
+#### Example Ingress Configuration
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: example-ingress
+ namespace: default
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /
+spec:
+ rules:
+ - host: example.com
+ http:
+ paths:
+ - path: /foo
+ pathType: Prefix
+ backend:
+ service:
+ name: foo-service
+ port:
+ number: 80
+```
+
+### 5. Save the Output
+
+The command will output the equivalent Gateway API resources in YAML/JSON format to stdout. Save this output to a file for further use.
+
+```sh
+./ingress2gateway print > gateway-resources.yaml
+```
+
+### 6. Apply the Translated Resources
+
+Apply the translated Gateway API resources to your cluster.
+
+```sh
+kubectl apply -f gateway-resources.yaml
+```
+
+### 7. Create a Gateway Resource
+
+Create a `Gateway` resource specifying the `GatewayClass` created earlier and including the necessary listeners.
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: Gateway
+metadata:
+ name: example-gateway
+ namespace: default
+spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ hostname: example.com
+```
+
+Apply this resource:
+
+```sh
+kubectl apply -f gateway.yaml
+```
+
+### 8. Validate the Migration
+
+Ensure the HTTPRoutes and Gateways are correctly set up and that traffic is being routed as expected. Validate the new configuration by checking the status of the Gateway and HTTPRoute resources.
+
+```sh
+kubectl get gateways
+kubectl get httproutes
+```
+
+### 9. Monitor and Troubleshoot
+
+Monitor the Envoy Gateway logs and metrics to ensure everything is functioning correctly. Troubleshoot any issues by reviewing the Gateway and HTTPRoute statuses and Envoy Gateway controller logs.
+
+## Summary
+
+By following this guide, users can effectively migrate their existing Ingress resources to Envoy Gateway using the Ingress2gateway package. Creating a GatewayClass and linking it to the Envoy Gateway controller ensures that the translated resources are properly programmed in the data plane, providing a seamless transition to the Envoy Gateway environment.
\ No newline at end of file
diff --git a/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md b/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md
index 9626dc93752..9fddf7dc576 100644
--- a/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md
+++ b/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md
@@ -80,11 +80,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-* After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
## Testing
@@ -110,7 +106,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -150,7 +145,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -194,7 +188,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -234,7 +227,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -272,12 +264,91 @@ kubectl patch httproute backend --type=json --patch '
* Test it out by specifying a path apart from `/get`
-```
-$ curl --header "Host: www.example.com" http://localhost:8888/find
+```shell
+$ curl --header "Host: www.example.com" http://$GATEWAY_HOST/find
Handling connection for 8888
could not find what you are looking for
```
+### Customize VirtualHost by name
+
+* Use EnvoyProxy's `include_attempt_count_in_response` feature to include the attempt count as header in the downstream response.
+* Apply the configuration
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <//
+ name: default/eg/http
+ operation:
+ op: add
+ # Every virtual_host that ends with 'www_example_com' (using RegEx Filter)
+ jsonPath: "..virtual_hosts[?match(@.name, '.*www_example_com')]"
+ # If the property does not exists, it can not be selected with jsonPath
+ # Therefore the new property must be set in path
+ path: "include_attempt_count_in_response"
+ value: true
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyPatchPolicy
+metadata:
+ name: include-attempts
+ namespace: default
+spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
+ type: JSONPatch
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
+ # The RouteConfiguration name is of the form //
+ name: default/eg/http
+ operation:
+ op: add
+ # Every virtual_host that ends with 'www_example_com' (using RegEx Filter)
+ jsonPath: "..virtual_hosts[?match(@.name, '.*www_example_com')]"
+ # If the property does not exists, it can not be selected with jsonPath
+ # Therefore the new property must be set in path
+ path: "include_attempt_count_in_response"
+ value: true
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+* Test it out by looking at the response headers
+
+```
+$ curl -v --header "Host: www.example.com" http://localhost:8888/
+...
+< x-envoy-attempt-count: 1
+...
+```
+
## Debugging
### Runtime
@@ -321,7 +392,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
status:
conditions:
@@ -344,7 +414,7 @@ status:
## Caveats
-This API will always be an unstable API and the same outcome cannot be garunteed
+This API will always be an unstable API and the same outcome cannot be guaranteed
across versions for these reasons
* The Envoy Proxy API might deprecate and remove API fields
* Envoy Gateway might alter the xDS translation creating a different xDS output
diff --git a/site/content/en/latest/tasks/extensibility/ext-proc.md b/site/content/en/latest/tasks/extensibility/ext-proc.md
index f6b8b5c741a..910332f4740 100644
--- a/site/content/en/latest/tasks/extensibility/ext-proc.md
+++ b/site/content/en/latest/tasks/extensibility/ext-proc.md
@@ -106,10 +106,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
@@ -132,10 +132,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
diff --git a/site/content/en/latest/tasks/extensibility/extension-server.md b/site/content/en/latest/tasks/extensibility/extension-server.md
index 922f0de7c8e..e1d6b471c11 100644
--- a/site/content/en/latest/tasks/extensibility/extension-server.md
+++ b/site/content/en/latest/tasks/extensibility/extension-server.md
@@ -1,5 +1,6 @@
---
title: "Envoy Gateway Extension Server"
+linkTitle: "Extension Server"
---
This task explains how to extend Envoy Gateway using an Extension Server. Envoy Gateway
@@ -87,6 +88,10 @@ image name and tag.
* Grant Envoy Gateway's `ServiceAccount` permission to access the extension server's CRD
```shell
+ kubectl create clusterrole listener-context-example-status-update \
+ --verb=update \
+ --resource=ListenerContextExample/status
+
kubectl create clusterrole listener-context-example-viewer \
--verb=get,list,watch \
--resource=ListenerContextExample
@@ -94,6 +99,10 @@ image name and tag.
kubectl create clusterrolebinding envoy-gateway-listener-context \
--clusterrole=listener-context-example-viewer \
--serviceaccount=envoy-gateway-system:envoy-gateway
+
+ kubectl create clusterrolebinding envoy-gateway-listener-context-status \
+ --clusterrole=listener-context-example-status-update \
+ --serviceaccount=envoy-gateway-system:envoy-gateway
```
* Configure Envoy Gateway to use the Extension Server
diff --git a/site/content/en/latest/tasks/extensibility/wasm.md b/site/content/en/latest/tasks/extensibility/wasm.md
index 6cb3d1092df..baad6a5804f 100644
--- a/site/content/en/latest/tasks/extensibility/wasm.md
+++ b/site/content/en/latest/tasks/extensibility/wasm.md
@@ -16,7 +16,7 @@ This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute]
## Configuration
-Envoy Gateway supports two types of Wasm extensions:
+Envoy Gateway supports two types of Wasm extensions:
* HTTP Wasm Extension: The Wasm extension is fetched from a remote URL.
* Image Wasm Extension: The Wasm extension is packaged as an OCI image and fetched from an image registry.
@@ -37,8 +37,8 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
@@ -47,7 +47,7 @@ spec:
code:
type: HTTP
http:
- url: https://raw.githubusercontent.com/envoyproxy/envoy/main/examples/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
+ url: https://raw.githubusercontent.com/envoyproxy/examples/main/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0
EOF
```
@@ -63,18 +63,18 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
- - name: wasm-filter
- rootID: my_root_id
- code:
- type: HTTP
- http:
- url: https://raw.githubusercontent.com/envoyproxy/envoy/main/examples/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
- sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0
+ - name: wasm-filter
+ rootID: my_root_id
+ code:
+ type: HTTP
+ http:
+ url: https://raw.githubusercontent.com/envoyproxy/examples/main/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
+ sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0
```
{{% /tab %}}
@@ -100,8 +100,8 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
@@ -125,17 +125,17 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
- - name: wasm-filter
- rootID: my_root_id
- code:
- type: Image
- image:
- url: zhaohuabing/testwasm:v0.0.1
+ - name: wasm-filter
+ rootID: my_root_id
+ code:
+ type: Image
+ image:
+ url: zhaohuabing/testwasm:v0.0.1
```
{{% /tab %}}
diff --git a/site/content/en/latest/tasks/observability/gateway-observability.md b/site/content/en/latest/tasks/observability/gateway-observability.md
index 6e0040b4f5d..f23eb9097cf 100644
--- a/site/content/en/latest/tasks/observability/gateway-observability.md
+++ b/site/content/en/latest/tasks/observability/gateway-observability.md
@@ -86,11 +86,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in:
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
### Enable Open Telemetry sink in Envoy Gateway
@@ -157,11 +153,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in:
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
Verify OTel-Collector metrics:
diff --git a/site/content/en/latest/tasks/observability/proxy-accesslog.md b/site/content/en/latest/tasks/observability/proxy-accesslog.md
index fb0200f1739..17d444b8636 100644
--- a/site/content/en/latest/tasks/observability/proxy-accesslog.md
+++ b/site/content/en/latest/tasks/observability/proxy-accesslog.md
@@ -249,3 +249,62 @@ Envoy Gateway provides additional metadata about the K8s resources that were tra
For example, details about the `HTTPRoute` and `GRPCRoute` (kind, group, name, namespace and annotations) are available
for access log formatter using the `METADATA` operator. To enrich logs, users can add log operator such as:
`%METADATA(ROUTE:envoy-gateway:resources)%` to their access log format.
+
+## Access Log Types
+
+By default, Access Log settings would apply to:
+- All Routes
+- If traffic is not matched by any Route known to Envoy, the Listener would emit the access log instead
+
+Users may wish to customize this behavior:
+- Emit Access Logs by all Listeners for all traffic with specific settings
+- Do not emit Route-oriented access logs when a route is not matched.
+
+To achieve this, users can select if Access Log settings follow the default behavior or apply specifically to
+Routes or Listeners by specifying the setting's type.
+
+**Note**: When users define their own Access Log settings (with or without a type), the default Envoy Gateway
+file access log is no longer configured. It can be re-enabled explicitly by adding empty settings for the desired components.
+
+In the following example:
+- Route Access logs would use the default Envoy Gateway format and sink
+- Listener Access logs are customized to report transport-level failures and connection attributes
+
+```shell
+kubectl apply -f - <}}
diff --git a/site/content/en/latest/tasks/observability/rate-limit-observability.md b/site/content/en/latest/tasks/observability/rate-limit-observability.md
index a0e523d6c8a..ec1244f731e 100644
--- a/site/content/en/latest/tasks/observability/rate-limit-observability.md
+++ b/site/content/en/latest/tasks/observability/rate-limit-observability.md
@@ -91,8 +91,4 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-After updating the ConfigMap, you will need to restart the envoy-gateway deployment so the configuration kicks in:
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
diff --git a/site/content/en/latest/tasks/operations/customize-envoyproxy.md b/site/content/en/latest/tasks/operations/customize-envoyproxy.md
index bfcc3d6e07a..9c5ab5fe177 100644
--- a/site/content/en/latest/tasks/operations/customize-envoyproxy.md
+++ b/site/content/en/latest/tasks/operations/customize-envoyproxy.md
@@ -3,14 +3,68 @@ title: "Customize EnvoyProxy"
---
Envoy Gateway provides an [EnvoyProxy][] CRD that can be linked to the ParametersRef
-in GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
+in a Gateway and GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
Service. To learn more about GatewayClass and ParametersRef, please refer to [Gateway API documentation][].
## Prerequisites
{{< boilerplate prerequisites >}}
-Before you start, you need to add `ParametersRef` in GatewayClass, and refer to EnvoyProxy Config:
+Before you start, you need to add `Infrastructure.ParametersRef` in Gateway, and refer to EnvoyProxy Config:
+**Note**: `MergeGateways` cannot be set to `true` in your EnvoyProxy config if attaching to the Gateway.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+You can also attach the EnvoyProxy resource to the GatewayClass using the `parametersRef` field.
+This configuration is discouraged if you plan on creating multiple Gateways linking to the same
+GatewayClass and would like different infrastructure configurations for each of them.
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -27,7 +81,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
EOF
```
@@ -47,7 +101,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
```
{{% /tab %}}
@@ -66,7 +120,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -86,7 +140,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -118,7 +172,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -139,7 +193,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -167,7 +221,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -190,7 +244,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -220,7 +274,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -247,7 +301,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -279,7 +333,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -304,7 +358,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -338,7 +392,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -367,7 +421,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -403,7 +457,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -425,7 +479,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -444,13 +498,14 @@ After applying the config, you can get the envoyproxy service, and see annotatio
## Customize EnvoyProxy Bootstrap Config
You can customize the EnvoyProxy bootstrap config via EnvoyProxy Config.
-There are two ways to customize it:
+There are three ways to customize it:
* Replace: the whole bootstrap config will be replaced by the config you provided.
* Merge: the config you provided will be merged into the default bootstrap config.
+* JSONPatch: the list of JSON Patches you provided will be applied to the bootstrap config. JSON Patch is a standard format specified in [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902/).
{{< tabpane text=true >}}
-{{% tab header="Apply from stdin" %}}
+{{% tab header="Replace: apply from stdin" %}}
```shell
cat <}}
-You can use [egctl translate][]
+You can use [egctl x translate][]
to get the default xDS Bootstrap configuration used by Envoy Gateway.
After applying the config, the bootstrap config will be overridden by the new config you provided.
Any errors in the configuration will be surfaced as status within the `GatewayClass` resource.
-You can also validate this configuration using [egctl translate][].
+You can also validate this configuration using [egctl x translate][].
## Customize EnvoyProxy Horizontal Pod Autoscaler
@@ -648,7 +742,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -676,7 +770,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -712,7 +806,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -729,7 +823,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -755,7 +849,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -791,7 +885,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -834,7 +928,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -859,7 +953,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -917,7 +1011,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
@@ -937,7 +1031,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
@@ -949,6 +1043,53 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
+## Customize EnvoyProxy IP Family
+
+You can customize the IP family configuration for EnvoyProxy via the EnvoyProxy Config.
+This allows the Envoy Proxy fleet to serve external clients over IPv4 as well as IPv6.
+
+The below configuration sets the `ipFamily` to `DualStack` to allow ingressing IPv4 as well as IPv6 traffic.
+
+**Note**: Envoy Gateway relies on the [Service](https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services) spec of the BackendRef resource (linked to xRoutes) to decide which type of IP addresses to use to route to them.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After applying the config, the EnvoyProxy deployment will be configured to use the specified IP family. When set to `DualStack`, both IPv4 and IPv6 networking will be enabled.
+
+**Note**: Your cluster must support the selected IP family configuration. For DualStack support, ensure your Kubernetes cluster is properly configured for dual-stack networking.
+
[Gateway API documentation]: https://gateway-api.sigs.k8s.io/
[EnvoyProxy]: ../../../api/extension_types#envoyproxy
-[egctl translate]: ../egctl/#validating-gateway-api-configuration
+[egctl x translate]: ../operations/egctl#egctl-experimental-translate
\ No newline at end of file
diff --git a/site/content/en/latest/tasks/operations/standalone-deployment-mode.md b/site/content/en/latest/tasks/operations/standalone-deployment-mode.md
new file mode 100644
index 00000000000..88a5c1b98c2
--- /dev/null
+++ b/site/content/en/latest/tasks/operations/standalone-deployment-mode.md
@@ -0,0 +1,130 @@
+---
+title: "Standalone Deployment Mode"
+---
+
+{{% alert title="Notice" color="warning" %}}
+
+Standalone mode is an experimental feature, please **DO NOT** use it in production.
+
+{{% /alert %}}
+
+Envoy Gateway also supports running in standalone mode. In this mode, Envoy Gateway
+does not need to rely on Kubernetes and can be deployed directly on bare metal or virtual machines.
+
+Currently, Envoy Gateway only support the file provider and the host infrastructure provider combinations.
+
+- The file provider will configure the Envoy Gateway to get all gateway-api resources from file system.
+- The host infrastructure provider will configure the Envoy Gateway to deploy one Envoy Proxy as a host process.
+
+## Quick Start
+
+In this quick-start, we will run Envoy Gateway in standalone mode with the file provider
+and the host infrastructure provider.
+
+### Prerequisites
+
+Create a local directory just for testing:
+
+```shell
+mkdir -p /tmp/envoy-gateway-test
+```
+
+As we do not provide the Envoy Gateway binary in latest release,
+you can compile this binary on your own from project by using command:
+
+```shell
+make build
+```
+
+The compiled binary lies in `bin/{os}/{arch}/envoy-gateway`.
+
+### Create Certificates
+
+All runners in Envoy Gateway are using TLS connection, so create these TLS certificates locally to
+ensure the Envoy Gateway works properly.
+
+```shell
+envoy-gateway certgen --local
+```
+
+### Start Envoy Gateway
+
+Start Envoy Gateway by the following command:
+
+```shell
+envoy-gateway server --config-path standalone.yaml
+```
+
+with `standalone.yaml` configuration:
+
+```yaml
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyGateway
+gateway:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+provider:
+ type: Custom
+ custom:
+ resource:
+ type: File
+ file:
+ paths: ["/tmp/envoy-gateway-test"]
+ infrastructure:
+ type: Host
+ host: {}
+logging:
+ level:
+ default: info
+extensionApis:
+ enableBackend: true
+```
+
+As you can see, we have enabled the [Backend][] API, this API will be used to represent our local endpoints.
+
+### Trigger an Update
+
+Any changes under watched `paths` will be considered as an update by the file provider.
+
+For instance, copying example file into `/tmp/envoy-gateway-test/` will trigger an update of gateway-api resources:
+
+```shell
+cp examples/standalone/quickstart.yaml /tmp/envoy-gateway-test/quickstart.yaml
+```
+
+From the Envoy Gateway log, you should be able to observe that the Envoy Proxy has been started, and its admin address has been returned.
+
+### Test Connection
+
+Starts a simple local server as an endpoint:
+
+```shell
+python3 -m http.server 3000
+```
+
+Curl the example server through Envoy Proxy:
+
+```shell
+curl --verbose --header "Host: www.example.com" http://0.0.0.0:8888/
+```
+
+```console
+* Trying 0.0.0.0:8888...
+* Connected to 0.0.0.0 (127.0.0.1) port 8888 (#0)
+> GET / HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/7.81.0
+> Accept: */*
+>
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 200 OK
+< server: SimpleHTTP/0.6 Python/3.10.12
+< date: Sat, 26 Oct 2024 13:20:34 GMT
+< content-type: text/html; charset=utf-8
+< content-length: 1870
+<
+...
+* Connection #0 to host 0.0.0.0 left intact
+```
+
+
+[Backend]: ../../../api/extension_types#backend
diff --git a/site/content/en/latest/tasks/quickstart.md b/site/content/en/latest/tasks/quickstart.md
index 03d7b6de842..e1943c21e92 100644
--- a/site/content/en/latest/tasks/quickstart.md
+++ b/site/content/en/latest/tasks/quickstart.md
@@ -12,7 +12,7 @@ A Kubernetes cluster.
__Note:__ Refer to the [Compatibility Matrix](/news/releases/matrix) for supported Kubernetes versions.
-__Note:__ In case your Kubernetes cluster, does not have a LoadBalancer implementation, we recommend installing one
+__Note:__ In case your Kubernetes cluster does not have a LoadBalancer implementation, we recommend installing one
so the `Gateway` resource has an Address associated with it. We recommend using [MetalLB](https://metallb.universe.tf/installation/).
__Note:__ For Mac user, you need install and run [Docker Mac Net Connect](https://github.com/chipmk/docker-mac-net-connect) to make the Docker network work.
@@ -92,34 +92,6 @@ curl --verbose --header "Host: www.example.com" http://localhost:8888/get
{{% /tab %}}
{{< /tabpane >}}
-## v1.1 Upgrade Notes
-
-Due to breaking changes in the Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1.
-
-Delete `BackendTLSPolicy` CRD (and resources):
-
-```shell
-kubectl delete crd backendtlspolicies.gateway.networking.k8s.io
-```
-
-Update Gateway-API and Envoy Gateway CRDs:
-
-```shell
-helm pull oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 --untar
-kubectl apply -f ./gateway-helm/crds/gatewayapi-crds.yaml
-kubectl apply -f ./gateway-helm/crds/generated
-```
-
-Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes)
-
-Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef.
-
-Install Envoy Gateway v1.1.0:
-
-```shell
-helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system
-```
-
## What to explore next?
In this quickstart, you have:
diff --git a/site/content/en/latest/tasks/security/backend-tls.md b/site/content/en/latest/tasks/security/backend-tls.md
index c30777f69f3..945a1f5ff98 100644
--- a/site/content/en/latest/tasks/security/backend-tls.md
+++ b/site/content/en/latest/tasks/security/backend-tls.md
@@ -17,7 +17,7 @@ Envoy Gateway supports the Gateway-API defined [BackendTLSPolicy][].
## TLS Certificates
-Generate the certificates and keys used by the backend to terminate TLS connections from the Gateways.
+Generate the certificates and keys used by the backend to terminate TLS connections from the Gateways.
Create a root certificate and private key to sign certificates:
@@ -25,11 +25,30 @@ Create a root certificate and private key to sign certificates:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout ca.key -out ca.crt
```
-Create a certificate and a private key for `www.example.com`:
+Create a certificate and a private key for `www.example.com`.
+
+First, create an openssl configuration file:
```shell
-openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization" -addext "subjectAltName = DNS:www.example.com"
-openssl x509 -req -days 365 -CA ca.crt -CAkey ca.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt
+cat > openssl.conf <}}
{{% tab header="Apply from stdin" %}}
@@ -136,6 +155,9 @@ spec:
Create a [BackendTLSPolicy][] instructing Envoy Gateway to establish a TLS connection with the backend and validate the backend certificate is issued by a trusted CA and contains an appropriate DNS SAN.
+Note: SectionName is an optional field that specifies the name of the port in the target backend. This example uses a Kubernetes Service as the backend target, so the sectionName is set to `https` to match the port name in the Service.
+If the target is a [Backend] resource, the `sectionName` field should be set to the port number of the backend.
+
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -151,7 +173,7 @@ spec:
- group: ''
kind: Service
name: tls-backend
- sectionName: "443"
+ sectionName: https
validation:
caCertificateRefs:
- name: example-ca
@@ -177,7 +199,7 @@ spec:
- group: ''
kind: Service
name: tls-backend
- sectionName: "443"
+ sectionName: https
validation:
caCertificateRefs:
- name: example-ca
@@ -279,8 +301,8 @@ Inspect the output and see that the response contains the details of the TLS han
## Customize backend TLS Parameters
-In addition to enablement of backend TLS with the Gateway-API BackendTLSPolicy, Envoy Gateway supports customizing TLS parameters.
-To achieve this, the [EnvoyProxy][] resource can be used to specify TLS parameters. We will customize the TLS version in this example.
+In addition to enablement of backend TLS with the Gateway-API BackendTLSPolicy, Envoy Gateway supports customizing TLS parameters.
+To achieve this, the [EnvoyProxy][] resource can be used to specify TLS parameters. We will customize the TLS version in this example.
First, you need to add ParametersRef in GatewayClass, and refer to EnvoyProxy Config:
@@ -371,7 +393,7 @@ curl -v -HHost:www.example.com --resolve "www.example.com:80:127.0.0.1" \
http://www.example.com:80/get
```
-Inspect the output and see that the response contains the details of the TLS handshake between Envoy and the backend.
+Inspect the output and see that the response contains the details of the TLS handshake between Envoy and the backend.
The TLS version is now TLS1.3, as configured in the EnvoyProxy resource. The TLS cipher is also changed, since TLS1.3 supports different ciphers from TLS1.2.
```shell
@@ -387,3 +409,4 @@ The TLS version is now TLS1.3, as configured in the EnvoyProxy resource. The TLS
[BackendTLSPolicy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
[EnvoyProxy]: ../../api/extension_types#envoyproxy
+[Backend]: ../../api/extension_types#backend
diff --git a/site/content/en/latest/tasks/security/basic-auth.md b/site/content/en/latest/tasks/security/basic-auth.md
index 79e48156056..cc0ec54ada1 100644
--- a/site/content/en/latest/tasks/security/basic-auth.md
+++ b/site/content/en/latest/tasks/security/basic-auth.md
@@ -109,10 +109,10 @@ kind: SecurityPolicy
metadata:
name: basic-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
basicAuth:
users:
name: "basic-auth"
@@ -130,10 +130,10 @@ kind: SecurityPolicy
metadata:
name: basic-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
basicAuth:
users:
name: "basic-auth"
@@ -194,7 +194,6 @@ curl -kv -H "Host: www.example.com" -u 'foo:bar' "https://${GATEWAY_HOST}/"
The request should be allowed and you should see the response from the backend service.
-```shell
## Clean-Up
diff --git a/site/content/en/latest/tasks/security/cors.md b/site/content/en/latest/tasks/security/cors.md
index 129e318cc6c..90a972ce4ca 100644
--- a/site/content/en/latest/tasks/security/cors.md
+++ b/site/content/en/latest/tasks/security/cors.md
@@ -31,8 +31,8 @@ kind: SecurityPolicy
metadata:
name: cors-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
cors:
@@ -62,8 +62,8 @@ kind: SecurityPolicy
metadata:
name: cors-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
cors:
diff --git a/site/content/en/latest/tasks/security/ext-auth.md b/site/content/en/latest/tasks/security/ext-auth.md
index e0f30e0310f..1d1625d5780 100644
--- a/site/content/en/latest/tasks/security/ext-auth.md
+++ b/site/content/en/latest/tasks/security/ext-auth.md
@@ -103,15 +103,15 @@ kind: SecurityPolicy
metadata:
name: ext-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extAuth:
http:
- backendRef:
- name: http-ext-auth
- port: 9002
+ backendRefs:
+ - name: http-ext-auth
+ port: 9002
headersToBackend: ["x-current-user"]
EOF
```
@@ -127,15 +127,15 @@ kind: SecurityPolicy
metadata:
name: ext-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extAuth:
http:
- backendRef:
- name: http-ext-auth
- port: 9002
+ backendRefs:
+ - name: http-ext-auth
+ port: 9002
headersToBackend: ["x-current-user"]
```
@@ -289,15 +289,15 @@ kind: SecurityPolicy
metadata:
name: ext-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extAuth:
grpc:
- backendRef:
- name: grpc-ext-auth
- port: 9002
+ backendRefs:
+ - name: grpc-ext-auth
+ port: 9002
EOF
```
@@ -312,15 +312,15 @@ kind: SecurityPolicy
metadata:
name: ext-auth-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extAuth:
grpc:
- backendRef:
- name: grpc-ext-auth
- port: 9002
+ backendRefs:
+ - name: grpc-ext-auth
+ port: 9002
```
{{% /tab %}}
diff --git a/site/content/en/latest/tasks/security/jwt-authentication.md b/site/content/en/latest/tasks/security/jwt-authentication.md
index 0468d572f2b..e4361b6354f 100644
--- a/site/content/en/latest/tasks/security/jwt-authentication.md
+++ b/site/content/en/latest/tasks/security/jwt-authentication.md
@@ -91,7 +91,7 @@ A `401` HTTP response code should be returned.
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
__Note:__ The above command decodes and returns the token's payload. You can replace `f2` with `f1` to view the token's
@@ -128,7 +128,7 @@ Error invoking method "yages.Echo/Ping": rpc error: code = Unauthenticated desc
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
__Note:__ The above command decodes and returns the token's payload. You can replace `f2` with `f1` to view the token's
diff --git a/site/content/en/latest/tasks/security/jwt-claim-authorization.md b/site/content/en/latest/tasks/security/jwt-claim-authorization.md
new file mode 100644
index 00000000000..2e67ea7ffe9
--- /dev/null
+++ b/site/content/en/latest/tasks/security/jwt-claim-authorization.md
@@ -0,0 +1,226 @@
+---
+title: "JWT Claim-Based Authorization"
+---
+
+This task provides instructions for configuring JWT claim-based authorization. JWT claim-based authorization checks if an incoming request has the required JWT claims before routing the request to a backend service.
+
+Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure JWT claim-based authorization.
+
+This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HTTPRoute] or [GRPCRoute][GRPCRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## Configuration
+
+### Create a SecurityPolicy
+
+Please note that the JWT claim-based authorization requires the JWT token to be present in the request. A JWT authentication must be configured in the same SecurityPolicy to validate the JWT token and extract the claims.
+
+The below SecurityPolicy configuration allows requests with a valid JWT token that has the following claims:
+- `user.name` claim with the value `John Doe`
+- `user.roles` claim with the value `admin`
+- `scope` claim with the values `read`, `add`, and `modify`
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/authorization-jwt-claim -o yaml
+```
+
+## Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+Define a JWT token with the required claims.
+
+```shell
+export VALID_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImI1MjBiM2MyYzRiZDc1YTEwZTljZWJjOTU3NjkzM2RjIn0.eyJpc3MiOiJodHRwczovL2Zvby5iYXIuY29tIiwic3ViIjoiMTIzNDU2Nzg5MCIsInVzZXIiOnsibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqb2huLmRvZUBleGFtcGxlLmNvbSIsInJvbGVzIjpbImFkbWluIiwiZWRpdG9yIl19LCJwcmVtaXVtX3VzZXIiOnRydWUsImlhdCI6MTUxNjIzOTAyMiwic2NvcGUiOiJyZWFkIGFkZCBkZWxldGUgbW9kaWZ5In0.P36iAlmiRCC79OiB3vstF5Q_9OqUYAMGF3a3H492GlojbV6DcuOz8YIEYGsRSWc-BNJaBKlyvUKsKsGVPtYbbF8ajwZTs64wyO-zhd2R8riPkg_HsW7iwGswV12f5iVRpfQ4AG2owmdOToIaoch0aym89He1ZzEjcShr9olgqlAbbmhnk-namd1rP-xpzPnWhhIVI3mCz5hYYgDTMcM7qbokM5FzFttTRXAn5_Luor23U1062Ct_K53QArwxBvwJ-QYiqcBycHf-hh6sMx_941cUswrZucCpa-EwA3piATf9PKAyeeWHfHV9X-y8ipGOFg3mYMMVBuUZ1lBkJCik9f9kboRY6QzpOISARQj9PKMXfxZdIPNuGmA7msSNAXQgqkvbx04jMwb9U7eCEdGZztH4C8LhlRjgj0ZdD7eNbRjeH2F6zrWyMUpGWaWyq6rMuP98W2DWM5ZflK6qvT1c7FuFsWPvWLkgxQwTWQKrHdKwdbsu32Sj8VtUBJ0-ddEb"
+```
+
+Decode the JWT token to verify that it has the required claims.
+
+```shell
+jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< $(echo ${VALID_TOKEN})
+```
+
+The decoded JWT token should look like the following:
+
+```json
+{
+ "typ": "JWT",
+ "alg": "RS256",
+ "kid": "b520b3c2c4bd75a10e9cebc9576933dc"
+}
+{
+ "iss": "https://foo.bar.com",
+ "sub": "1234567890",
+ "user": {
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "roles": [
+ "admin",
+ "editor"
+ ]
+ },
+ "premium_user": true,
+ "iat": 1516239022,
+ "scope": "read add delete modify"
+}
+```
+
+Send a request to the backend service with the valid JWT token:
+
+```shell
+curl -H "Host: www.example.com" -H "Authorization: Bearer ${VALID_TOKEN}" "http://${GATEWAY_HOST}/"
+```
+
+The request should be allowed and you should see the response from the backend service.
+
+Define a JWT token without the required claims.
+
+```shell
+export INVALID_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImI1MjBiM2MyYzRiZDc1YTEwZTljZWJjOTU3NjkzM2RjIn0.eyJpc3MiOiJodHRwczovL2Zvby5iYXIuY29tIiwic3ViIjoiMTIzNDU2Nzg5MCIsInVzZXIiOnsibmFtZSI6IkFsaWNlIFNtaXRoIiwiZW1haWwiOiJhbGljZS5zbWl0aEBleGFtcGxlLmNvbSIsInJvbGVzIjpbImRldmVsb3BlciJdfSwicHJlbWl1bV91c2VyIjpmYWxzZSwiaWF0IjoxNTE2MjM5MDIyLCJzY29wZSI6InJlYWQgYWRkIGRlbGV0ZSJ9.Da547nNXzuQXm5E7LuLAiyFswXsW4RDhuitD_rpadtR7PTwzzOsJoqrVWJ_u1jJDaOTWIpLF4gwxDoY-Aoz_couzXzlAbECLs45ZFoc_UdffpfIbGKqTZx8VtwKuDLFsAeDDDqqx1flxFhvXHftJJdZYr1FgFz9u-absMmRU90DLmEZX3Hnyc8k8eBgeiu6vsWUD0-aNy8cWkFRbwRggkGmucFyUTG8Z1MY3iyH5E66W-ISoX8G9bzE9PTxVAAPDTvefD5iLJPSDJ8qV69OuMCJ8Dczq0L9Dd_w0sF-D1s9MTvexmGg4zBWluJ3r-pU9NHEdhqBypehp_yH8xF5Rt9AE7stZ4oPFZNyfrtkE-4IOnSEkMmzcC65g_rscn0ycerv4N5ZNpkr0x2IYYM4iGuo-ULv5Htnli3rffST45kx1XA8cdsrT1D0K3aPxdIxDIk8sTJf5-WVqRyo-bwxXXltwQLB9jCM_7QbTWQBYAJwUpi-0RW4jCl44-42gZnXf"
+```
+
+Decode the JWT token to verify that it does not have the required claims.
+
+```shell
+jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< $(echo ${INVALID_TOKEN})
+```
+
+The decoded JWT token should look like the following:
+
+```json
+{
+ "typ": "JWT",
+ "alg": "RS256",
+ "kid": "b520b3c2c4bd75a10e9cebc9576933dc"
+}
+{
+ "iss": "https://foo.bar.com",
+ "sub": "1234567890",
+ "user": {
+ "name": "Alice Smith",
+ "email": "alice.smith@example.com",
+ "roles": [
+ "developer"
+ ]
+ },
+ "premium_user": false,
+ "iat": 1516239022,
+ "scope": "read add delete"
+}
+```
+
+Send a request to the backend service with the invalid JWT token:
+
+```shell
+curl -v -H "Host: www.example.com" -H "Authorization: Bearer ${INVALID_TOKEN}" "http://${GATEWAY_HOST}/"
+```
+
+The request should be denied and you should see a `403 Forbidden` response.
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the SecurityPolicy and the ClientTrafficPolicy
+
+```shell
+kubectl delete securitypolicy/authorization-jwt-claim
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[SecurityPolicy]: ../../../contributions/design/security-policy
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[GRPCRoute]: https://gateway-api.sigs.k8s.io/api-types/grpcroute
diff --git a/site/content/en/latest/tasks/security/mutual-tls.md b/site/content/en/latest/tasks/security/mutual-tls.md
index 4eed29a1c39..4ac9f96430a 100644
--- a/site/content/en/latest/tasks/security/mutual-tls.md
+++ b/site/content/en/latest/tasks/security/mutual-tls.md
@@ -88,11 +88,10 @@ metadata:
name: enable-mtls
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
tls:
clientValidation:
caCertificateRefs:
@@ -114,11 +113,10 @@ metadata:
name: enable-mtls
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
tls:
clientValidation:
caCertificateRefs:
diff --git a/site/content/en/latest/tasks/security/oidc.md b/site/content/en/latest/tasks/security/oidc.md
index f7890b5d198..d57e7d35ff3 100644
--- a/site/content/en/latest/tasks/security/oidc.md
+++ b/site/content/en/latest/tasks/security/oidc.md
@@ -85,7 +85,7 @@ kubectl get httproute/myapp -o yaml
## OIDC Authentication for a HTTPRoute
-OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with
+OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with
the same OIDC configuration, or at the HTTPRoute level to authenticate each HTTPRoute with different OIDC configurations.
This section demonstrates how to configure OIDC authentication for a specific HTTPRoute.
@@ -97,7 +97,7 @@ providers, including Auth0, Azure AD, Keycloak, Okta, OneLogin, Salesforce, UAA,
Follow the steps in the [Google OIDC documentation][google-oidc] to register an OIDC application. Please make sure the
redirect URL is set to the one you configured in the SecurityPolicy that you will create in the step below. In this example,
-the redirect URL is `http://www.example.com:8443/myapp/oauth2/callback`.
+the redirect URL is `https://www.example.com:8443/myapp/oauth2/callback`.
After registering the application, you should have the following information:
* Client ID: The client ID of the OIDC application.
@@ -117,9 +117,9 @@ kubectl create secret generic my-app-client-secret --from-literal=client-secret=
### Create a SecurityPolicy
**Please notice that the `redirectURL` and `logoutPath` must match the target HTTPRoute.** In this example, the target
-HTTPRoute is configured to match the host `www.example.com` and the path `/myapp`, so the `redirectURL` must be prefixed
-with `https://www.example.com:8443/myapp`, and `logoutPath` must be prefixed with`/myapp`, otherwise the OIDC authentication
-will fail because the redirect and logout requests will not match the target HTTPRoute and therefore can't be processed
+HTTPRoute is configured to match the host `www.example.com` and the path `/myapp`, so the `redirectURL` must be prefixed
+with `https://www.example.com:8443/myapp`, and `logoutPath` must be prefixed with`/myapp`, otherwise the OIDC authentication
+will fail because the redirect and logout requests will not match the target HTTPRoute and therefore can't be processed
by the OAuth2 filter on that HTTPRoute.
Note: please replace the ${CLIENT_ID} in the below yaml snippet with the actual Client ID that you got from the OIDC provider.
@@ -134,10 +134,10 @@ kind: SecurityPolicy
metadata:
name: oidc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
oidc:
provider:
issuer: "https://accounts.google.com"
@@ -160,10 +160,10 @@ kind: SecurityPolicy
metadata:
name: oidc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
oidc:
provider:
issuer: "https://accounts.google.com"
@@ -200,8 +200,8 @@ Put www.example.com in the /etc/hosts file in your test machine, so we can use t
127.0.0.1 www.example.com
```
-Open a browser and navigate to the `https://www.example.com:8443/myapp` address. You should be redirected to the Google
-login page. After you successfully login, you should see the response from the backend service.
+Open a browser and navigate to the `https://www.example.com:8443/myapp` address. You should be redirected to the Google
+login page. After you successfully login, you should see the response from the backend service.
Clean the cookies in the browser and try to access `https://www.example.com:8443/foo` address. You should be able to see
this page since the path `/foo` is not protected by the OIDC policy.
@@ -221,12 +221,80 @@ If you haven't registered an OIDC application, follow the steps in the previous
If you haven't created a kubernetes secret, follow the steps in the previous section to create a kubernetes secret.
+### Create an HTTPRoute with a different subdomain
+
+Let's create another HTTPRoute in the same Gateway, but with a different subdomain.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the HTTPRoute status:
+
+```shell
+kubectl get httproute/foo -o yaml
+```
+
### Create a SecurityPolicy
-Create or update the SecurityPolicy to target the Gateway instead of the HTTPRoute. **Please notice that the `redirectURL`
-and `logoutPath` must match one of the HTTPRoutes associated with the Gateway.** In this example, the target Gateway has
-two HTTPRoutes associated with it, one with the host `www.example.com` and the path `/myapp`, and the other with the host
-`www.example.com` and the path `/`. Either one of the HTTPRoutes can be used to match the `redirectURL` and `logoutPath`.
+Create or update the SecurityPolicy to target the Gateway instead of the HTTPRoute. **Please notice that the `redirectURL`
+and `logoutPath` must match one of the HTTPRoutes associated with the Gateway.** In this example, the target Gateway has
+three HTTPRoutes associated with it, one with the host `www.example.com` and the path `/myapp`, one with the host
+`www.example.com` and the path `/`, and one with the host `foo.example.com` and the path `/`. Any of these HTTPRoutes
+can be used to match the `redirectURL` and `logoutPath`.
+
+By default, the access token and ID token cookies are set to the host of the request, excluding subdomains. To allow the
+token cookies to be shared across subdomains and prevent users from having to log in again when switching between subdomains,
+the `cookieDomain` field needs to be set to the root domain. In this example, the root domain is `example.com`.
+
+Note: if a `cookieDomain` is added to an existing SecurityPolicy, the cookies in the browser must be cleared before sending a new request to the Gateway, otherwise the cookies with the old subdomain will take precedence and be sent to the Gateway, causing the OIDC authentication to fail.
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -238,10 +306,10 @@ kind: SecurityPolicy
metadata:
name: oidc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
oidc:
provider:
issuer: "https://accounts.google.com"
@@ -250,6 +318,7 @@ spec:
name: "my-app-client-secret"
redirectURL: "https://www.example.com:8443/myapp/oauth2/callback"
logoutPath: "/myapp/logout"
+ cookieDomain: "example.com"
EOF
```
@@ -264,10 +333,10 @@ kind: SecurityPolicy
metadata:
name: oidc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
oidc:
provider:
issuer: "https://accounts.google.com"
@@ -276,6 +345,7 @@ spec:
name: "my-app-client-secret"
redirectURL: "https://www.example.com:8443/myapp/oauth2/callback"
logoutPath: "/myapp/logout"
+ cookieDomain: "example.com"
```
{{% /tab %}}
@@ -287,16 +357,187 @@ Verify the SecurityPolicy configuration:
kubectl get securitypolicy/oidc-example -o yaml
```
+### Update the Listener TLS certificate to support multiple subdomains
+
+Create a multi-domain wildcard certificate for `*.example.com`.
+
+```shell
+openssl req -out wildcard.csr -newkey rsa:2048 -nodes -keyout wildcard.key -subj "/CN=*.example.com/O=example organization"
+openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in wildcard.csr -out wildcard.crt
+```
+
+Replace the TLS certificate of the Gateway with the wildcard certificate.
+
+```shell
+kubectl delete secret example-cert
+kubectl create secret tls example-cert --key=wildcard.key --cert=wildcard.crt
+```
+
### Testing
If you haven't done so, follow the steps in the previous section to port forward gateway port to localhost and put
www.example.com in the /etc/hosts file in your test machine.
-Open a browser and navigate to the `https://www.example.com:8443/foo` address. You should be redirected to the Google
+Also, put foo.example.com in the /etc/hosts file in your test machine.
+
+```shell
+...
+127.0.0.1 foo.example.com
+```
+
+Open a browser and navigate to the `https://www.example.com:8443/myapp` address. You should be redirected to the Google
login page. After you successfully login, you should see the response from the backend service.
-You can also try to access `https://www.example.com:8443/myapp` address. You should be able to see this page since the
-path `/myapp` is protected by the same OIDC policy.
+You can also try to access `https://foo.example.com:8443` and `https://www.example.com:8443/bar` addresses. You should
+be able to see the response from the backend service since these HTTPRoutes are also protected by the same OIDC config,
+and the cookies are shared across subdomains.
+
+## Connect to an OIDC Provider with Self-Signed Certificate
+
+In some scenarios, the OIDC provider may use a self-signed certificate. To connect to an OIDC provider with a self-signed certificate, you need to configure it using the [Backend] resource within the [SecurityPolicy]. Additionally, use the [BackendTLSPolicy] to specify the CA certificate required to authenticate the OIDC provider.
+
+The following example demonstrates how to configure the OIDC provider with a self-signed certificate.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+For more information about [Backend] and [BackendTLSPolicy], refer to the [Backend Routing][backend-routing] and [Backend TLS: Gateway to Backend][backend-tls] tasks.
## Clean-Up
@@ -308,6 +549,7 @@ Delete the SecurityPolicy, the secret and the HTTPRoute:
kubectl delete securitypolicy/oidc-example
kubectl delete secret/my-app-client-secret
kubectl delete httproute/myapp
+kubectl delete httproute/foo
```
## Next Steps
@@ -316,6 +558,10 @@ Checkout the [Developer Guide](../../../../contributions/develop) to get involve
[oidc]: https://openid.net/connect/
[google-oidc]: https://developers.google.com/identity/protocols/oauth2/openid-connect
-[SecurityPolicy]: ../../../../contributions/design/security-policy
+[SecurityPolicy]: ../../../api/extension_types#securitypolicy
[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[Backend]: ../../../api/extension_types#backend
+[BackendTLSPolicy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
+[backend-routing]: ../traffic/backend
+[backend-tls]: ../backend-tls
diff --git a/site/content/en/latest/tasks/security/private-key-provider.md b/site/content/en/latest/tasks/security/private-key-provider.md
index cf40a96e9e1..24544f67973 100644
--- a/site/content/en/latest/tasks/security/private-key-provider.md
+++ b/site/content/en/latest/tasks/security/private-key-provider.md
@@ -14,7 +14,9 @@ This task will walk you through the steps required to configure TLS Termination
## Prerequisites
-### For QAT
+{{< tabpane text=true >}}
+
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
- Install Linux kernel 5.17 or similar
- Ensure the node has QAT devices by checking the QAT physical function devices presented. [Supported Devices](https://intel.github.io/quickassist/qatlib/requirements.html#qat2-0-qatlib-supported-devices)
@@ -88,7 +90,9 @@ This task will walk you through the steps required to configure TLS Termination
kubectl get node -o yaml| grep qat.intel.com
```
-### For CryptoMB:
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
It required the node with 3rd generation Intel Xeon Scalable processor server processors, or later.
- For kubernetes Cluster, if not all nodes that support Intel® AVX-512 in Kubernetes cluster, you need to add some labels to divide these two kinds of nodes manually or using [NFD](https://github.com/kubernetes-sigs/node-feature-discovery).
@@ -110,6 +114,10 @@ It required the node with 3rd generation Intel Xeon Scalable processor server pr
cat /proc/cpuinfo |grep avx512f|grep avx512dq|grep avx512bw|grep avx512_vbmi2|grep avx512ifma
```
+{{% /tab %}}
+
+{{< /tabpane >}}
+
## Installation
* Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway.
@@ -161,11 +169,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-* After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in
-
- ```shell
- kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
- ```
+{{< boilerplate rollout-envoy-gateway >}}
## Create gateway for TLS termination
@@ -214,10 +218,14 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
-### Change EnvoyProxy configuration for QAT
+## Change EnvoyProxy configuration
Using the envoyproxy image with contrib extensions and add qat resources requesting, ensure the k8s scheduler find out a machine with required resource.
+{{< tabpane text=true >}}
+
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
+
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -285,7 +293,9 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
-### Change EnvoyProxy configuration for CryptoMB
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
Using the envoyproxy image with contrib extensions and add the node affinity to scheduling the Envoy Gateway pod on the machine with required CPU instructions.
@@ -386,9 +396,11 @@ spec:
Or using `preferredDuringSchedulingIgnoredDuringExecution` for best effort scheduling, or not doing any node affinity, just doing the random scheduling. The CryptoMB private key provider supports software fallback if the required CPU instructions aren't here.
-## Apply EnvoyPatchPolicy to enable private key provider
+{{% /tab %}}
+
+{{< /tabpane >}}
-### Benchmark before enabling private key provider
+## Benchmark before enabling private key provider
First follow the instructions in [TLS Termination for TCP](./tls-termination) to do the functionality test.
@@ -416,7 +428,11 @@ Benchmark the gateway with fortio.
fortio load -c 10 -k -qps 0 -t 30s -keepalive=false https://www.example.com:${NODE_PORT}
```
-### For QAT
+## Apply EnvoyPatchPolicy to enable private key provider
+
+{{< tabpane text=true >}}
+
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -433,7 +449,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
@@ -475,7 +490,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
@@ -503,7 +517,9 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
-### For CryptoMB
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -520,7 +536,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
@@ -562,7 +577,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
@@ -590,7 +604,11 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
-### Benchmark after enabling private key provider
+{{% /tab %}}
+
+{{< /tabpane >}}
+
+## Benchmark after enabling private key provider
First follow the instructions in [TLS Termination for TCP](./tls-termination) to do the functionality test again.
@@ -600,6 +618,8 @@ Benchmark the gateway with fortio.
fortio load -c 64 -k -qps 0 -t 30s -keepalive=false https://www.example.com:${NODE_PORT}
```
+## Benchmark Result
+
You will see a performance boost after private key provider enabled. For example, you will get results as below.
Without private key provider:
@@ -608,14 +628,26 @@ Without private key provider:
All done 43069 calls (plus 10 warmup) 6.966 ms avg, 1435.4 qps
```
-With CryptoMB private key provider, the QPS is over 2 times than without private key provider.
+{{< tabpane text=true >}}
-```shell
-All done 93983 calls (plus 128 warmup) 40.880 ms avg, 3130.5 qps
-```
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
With QAT private key provider, the QPS is over 3 times than without private key provider
```shell
All done 134746 calls (plus 128 warmup) 28.505 ms avg, 4489.6 qps
```
+
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
+
+With CryptoMB private key provider, the QPS is over 2 times than without private key provider.
+
+```shell
+All done 93983 calls (plus 128 warmup) 40.880 ms avg, 3130.5 qps
+```
+
+{{% /tab %}}
+
+{{< /tabpane >}}
diff --git a/site/content/en/latest/tasks/security/restrict-ip-access.md b/site/content/en/latest/tasks/security/restrict-ip-access.md
index cfc0fca5050..ab8965d7966 100644
--- a/site/content/en/latest/tasks/security/restrict-ip-access.md
+++ b/site/content/en/latest/tasks/security/restrict-ip-access.md
@@ -32,8 +32,8 @@ kind: SecurityPolicy
metadata:
name: authorization-client-ip
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
authorization:
@@ -57,17 +57,17 @@ kind: SecurityPolicy
metadata:
name: authorization-client-ip
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
authorization:
defaultAction: Deny
rules:
- - action: Allow
- principal:
- clientCIDRs:
- - 10.0.1.0/24
+ - action: Allow
+ principal:
+ clientCIDRs:
+ - 10.0.1.0/24
```
{{% /tab %}}
@@ -101,10 +101,10 @@ spec:
clientIPDetection:
xForwardedFor:
numTrustedHops: 1
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
EOF
```
@@ -122,10 +122,10 @@ spec:
clientIPDetection:
xForwardedFor:
numTrustedHops: 1
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
```
{{% /tab %}}
diff --git a/site/content/en/latest/tasks/security/secure-gateways.md b/site/content/en/latest/tasks/security/secure-gateways.md
index f0e5c8c2697..2c8d5043812 100644
--- a/site/content/en/latest/tasks/security/secure-gateways.md
+++ b/site/content/en/latest/tasks/security/secure-gateways.md
@@ -512,8 +512,88 @@ Since the multiple certificates are configured on the same Gateway listener, Env
{{% /tab %}}
{{< /tabpane >}}
+## Customize Gateway TLS Parameters
+
+In addition to enablement of TLS with Gateway-API, Envoy Gateway supports customizing TLS parameters.
+To achieve this, the [ClientTrafficPolicy][] resource can be used to specify TLS parameters.
+We will customize the minimum supported TLS version in this example to TLSv1.3.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+## Testing TLS Parameters
+
+Attempt to connecting using an unsupported TLS version:
+
+```shell
+curl -v -HHost:www.sample.com --resolve "www.sample.com:8443:127.0.0.1" \
+--cacert sample.com.crt --tlsv1.2 --tls-max 1.2 https://www.sample.com:8443/get -I
+
+[...]
+
+* ALPN: curl offers h2,http/1.1
+* (304) (OUT), TLS handshake, Client hello (1):
+* LibreSSL/3.3.6: error:1404B42E:SSL routines:ST_CONNECT:tlsv1 alert protocol version
+* Closing connection
+curl: (35) LibreSSL/3.3.6: error:1404B42E:SSL routines:ST_CONNECT:tlsv1 alert protocol version
+```
+
+The output shows that the connection fails due to an unsupported TLS protocol version used by the client. Now, connect
+to the Gateway without specifying a client version, and note that the connection is established with TLSv1.3.
+
+```shell
+curl -v -HHost:www.sample.com --resolve "www.sample.com:8443:127.0.0.1" \
+--cacert sample.com.crt https://www.sample.com:8443/get -I
+
+[...]
+
+* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
+```
+
## Next Steps
Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
[ReferenceGrant]: https://gateway-api.sigs.k8s.io/api-types/referencegrant/
+[ClientTrafficPolicy]: ../../api/extension_types#clienttrafficpolicy
\ No newline at end of file
diff --git a/site/content/en/latest/tasks/security/tls-cert-manager.md b/site/content/en/latest/tasks/security/tls-cert-manager.md
index 997a7ef254d..61ebb5c0162 100644
--- a/site/content/en/latest/tasks/security/tls-cert-manager.md
+++ b/site/content/en/latest/tasks/security/tls-cert-manager.md
@@ -75,7 +75,7 @@ EOF
We now have to patch the example Gateway to reference cert-manager:
```console
-$ kubectl patch gateway/eg --patch-file - <}}
-* After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
## Testing
@@ -204,7 +202,9 @@ curl -I -HHost:www.example.com http://${GATEWAY_HOST}/headers
[CVE-2021-25740]: https://nvd.nist.gov/vuln/detail/CVE-2021-25740
[upstream recommendations]: https://github.com/kubernetes/kubernetes/issues/103675
[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[TLSRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute
[Envoy Extension Policy]: ../../../api/extension_types#envoyextensionpolicy
+[Security Policy]: ../../../api/extension_types#oidcprovider
[Backend TLS Policy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
[EnvoyProxy]: ../../../api/extension_types#envoyproxy
[EnvoyGateway]: ../../../api/extension_types#envoygateway
diff --git a/site/content/en/latest/tasks/traffic/circuit-breaker.md b/site/content/en/latest/tasks/traffic/circuit-breaker.md
index 99887dabae9..6a359c5e0dc 100644
--- a/site/content/en/latest/tasks/traffic/circuit-breaker.md
+++ b/site/content/en/latest/tasks/traffic/circuit-breaker.md
@@ -73,10 +73,10 @@ kind: BackendTrafficPolicy
metadata:
name: circuitbreaker-for-route
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
circuitBreaker:
maxPendingRequests: 0
maxParallelRequests: 10
@@ -94,10 +94,10 @@ kind: BackendTrafficPolicy
metadata:
name: circuitbreaker-for-route
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
circuitBreaker:
maxPendingRequests: 0
maxParallelRequests: 10
diff --git a/site/content/en/latest/tasks/traffic/client-traffic-policy.md b/site/content/en/latest/tasks/traffic/client-traffic-policy.md
index a6b4a7f9f12..2099ea13685 100644
--- a/site/content/en/latest/tasks/traffic/client-traffic-policy.md
+++ b/site/content/en/latest/tasks/traffic/client-traffic-policy.md
@@ -33,9 +33,9 @@ metadata:
namespace: default
spec:
targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
tcpKeepalive:
idleTime: 20m
interval: 60s
@@ -55,10 +55,10 @@ metadata:
name: enable-tcp-keepalive-policy
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
tcpKeepalive:
idleTime: 20m
interval: 60s
@@ -212,10 +212,10 @@ metadata:
name: enable-proxy-protocol-policy
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
enableProxyProtocol: true
EOF
```
@@ -232,10 +232,10 @@ metadata:
name: enable-proxy-protocol-policy
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
enableProxyProtocol: true
```
@@ -350,9 +350,9 @@ metadata:
namespace: default
spec:
targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
clientIPDetection:
xForwardedFor:
numTrustedHops: 2
@@ -371,10 +371,10 @@ metadata:
name: http-client-ip-detection
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
clientIPDetection:
xForwardedFor:
numTrustedHops: 2
@@ -500,10 +500,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
timeout:
http:
requestReceivedTimeout: 2s
@@ -521,10 +521,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
timeout:
http:
requestReceivedTimeout: 2s
@@ -580,10 +580,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
timeout:
http:
idleTimeout: 5s
@@ -601,10 +601,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
timeout:
http:
idleTimeout: 5s
@@ -645,10 +645,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
connection:
bufferLimit: 1024
EOF
@@ -665,10 +665,10 @@ kind: ClientTrafficPolicy
metadata:
name: client-timeout
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
connection:
bufferLimit: 1024
```
diff --git a/site/content/en/latest/tasks/traffic/connection-limit.md b/site/content/en/latest/tasks/traffic/connection-limit.md
index 21f679e73f3..9c0e9bbc1fc 100644
--- a/site/content/en/latest/tasks/traffic/connection-limit.md
+++ b/site/content/en/latest/tasks/traffic/connection-limit.md
@@ -68,10 +68,10 @@ metadata:
name: connection-limit-ctp
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
connection:
connectionLimit:
value: 5
@@ -90,10 +90,10 @@ metadata:
name: connection-limit-ctp
namespace: default
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
connection:
connectionLimit:
value: 5
diff --git a/site/content/en/latest/tasks/traffic/direct-response.md b/site/content/en/latest/tasks/traffic/direct-response.md
new file mode 100644
index 00000000000..dfaa6755d4d
--- /dev/null
+++ b/site/content/en/latest/tasks/traffic/direct-response.md
@@ -0,0 +1,203 @@
+---
+title: "Direct Response"
+---
+
+Direct responses are valuable in cases where you want the gateway itself
+to handle certain requests without forwarding them to backend services.
+This task shows you how to configure them.
+
+## Installation
+
+Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+## Testing Direct Response
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/inline
+```
+
+```console
+* Trying 127.0.0.1:80...
+* Connected to 127.0.0.1 (127.0.0.1) port 80
+> GET /inline HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.4.0
+> Accept: */*
+>
+< HTTP/1.1 503 Service Unavailable
+< content-type: text/plain
+< content-length: 32
+< date: Sat, 02 Nov 2024 00:35:48 GMT
+<
+* Connection #0 to host 127.0.0.1 left intact
+Oops! Your request is not found.
+```
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/value-ref
+```
+
+```console
+* Trying 127.0.0.1:80...
+* Connected to 127.0.0.1 (127.0.0.1) port 80
+> GET /value-ref HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.4.0
+> Accept: */*
+>
+< HTTP/1.1 500 Internal Server Error
+< content-type: application/json
+< content-length: 34
+< date: Sat, 02 Nov 2024 00:35:55 GMT
+<
+* Connection #0 to host 127.0.0.1 left intact
+{"error": "Internal Server Error"}
+```
diff --git a/site/content/en/latest/tasks/traffic/failover.md b/site/content/en/latest/tasks/traffic/failover.md
new file mode 100644
index 00000000000..625d5e2afcd
--- /dev/null
+++ b/site/content/en/latest/tasks/traffic/failover.md
@@ -0,0 +1,566 @@
+---
+title: Failover
+---
+
+Active-passive failover in an API gateway setup is like having a backup plan in place to keep things
+running smoothly if something goes wrong. Here’s why it’s valuable:
+
+* Staying Online: When the main (or "active") backend has issues or goes offline,
+the fallback (or "passive") backend is ready to step in instantly.
+This helps keep your API accessible and your services running, so users don’t even notice any interruptions.
+
+* Automatic Switch Over: If a problem occurs, the system can automatically switch traffic over to the fallback backend.
+This avoids needing someone to jump in and fix things manually, which could take time and might even lead to mistakes.
+
+* Lower Costs: In an active-passive setup, the fallback backend doesn’t need to work all the time—it’s just on standby.
+This can save on costs (like cloud egress costs) compared to setups where both backend are running at full capacity.
+
+* Peace of Mind with Redundancy: Although the fallback backend isn’t handling traffic daily, it's there as a safety net.
+If something happens with the primary backend, the backup can take over immediately, ensuring your service doesn’t skip a beat.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## Test
+
+* We'll first create two services & deployments, called `active` and `passive`, representing an `active` and `passive` backend application.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+* Follow the instructions [here](./../../tasks/traffic/backend/#enable-backend) to enable the Backend API
+
+* Create two Backend resources that are used to represent the `active` backend and `passive` backend.
+Note, we've set `fallback: true` for the `passive` backend to indicate its a passive backend
+
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+* Lets create an HTTPRoute that can route to both these backends
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+* Lets configure a `BackendTrafficPolicy` with a passive health check setting to detect an transient errors.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+
+* Lets send 10 requests. You should see that they all go to the `active` backend.
+
+```shell
+for i in {1..10; do curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/test 2>/dev/null | jq .pod; done
+```
+
+```console
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+```
+
+* Lets simulate a failure in the `active` backend by changing the server listening port to `5000`
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+* Lets send 10 requests again. You should see them all being sent to the `passive` backend
+
+```shell
+for i in {1..10; do curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/test 2>/dev/null | jq .pod; done
+```
+
+```console
+parse error: Invalid numeric literal at line 1, column 9
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+```
+
+The first error can be avoided by configuring [retries](./../../tasks/traffic/retry.md).
diff --git a/site/content/en/latest/tasks/traffic/fault-injection.md b/site/content/en/latest/tasks/traffic/fault-injection.md
index 040dc18121f..82068c4cf55 100644
--- a/site/content/en/latest/tasks/traffic/fault-injection.md
+++ b/site/content/en/latest/tasks/traffic/fault-injection.md
@@ -37,8 +37,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-50-percent-abort
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: foo
faultInjection:
@@ -51,8 +51,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-delay
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: bar
faultInjection:
@@ -114,8 +114,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-50-percent-abort
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: foo
faultInjection:
@@ -128,8 +128,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-delay
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: bar
faultInjection:
@@ -211,8 +211,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-abort
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: GRPCRoute
name: yages
faultInjection:
@@ -251,8 +251,8 @@ kind: BackendTrafficPolicy
metadata:
name: fault-injection-abort
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: GRPCRoute
name: yages
faultInjection:
diff --git a/site/content/en/latest/tasks/traffic/global-rate-limit.md b/site/content/en/latest/tasks/traffic/global-rate-limit.md
index 9dd732a81ca..47eac33bc3e 100644
--- a/site/content/en/latest/tasks/traffic/global-rate-limit.md
+++ b/site/content/en/latest/tasks/traffic/global-rate-limit.md
@@ -214,11 +214,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-* After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
## Rate Limit Specific User
@@ -235,8 +231,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -264,8 +260,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -437,11 +433,11 @@ server: envoy
```
-## Rate Limit Distinct Users
+## Rate Limit Distinct Users Except Admin
Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differentiated based on the
value in the `x-user-id` header. Here, user `one` (recognised from the traffic flow using the header `x-user-id` and value `one`) will be rate limited at 3 requests/hour
-and so will user `two` (recognised from the traffic flow using the header `x-user-id` and value `two`).
+and so will user `two` (recognised from the traffic flow using the header `x-user-id` and value `two`). But if `x-user-id` is `admin`, it will not be rate limited even beyond 3 requests/hour.
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -453,8 +449,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -465,6 +461,9 @@ spec:
- headers:
- type: Distinct
name: x-user-id
+ - name: x-user-id
+ value: admin
+ invert: true
limit:
requests: 3
unit: Hour
@@ -482,8 +481,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -640,6 +639,47 @@ transfer-encoding: chunked
```
+But when the value for header `x-user-id` is set to `admin` and 4 requests are sent, all 4 of them should respond with 200 OK.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: admin" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+```
+
## Rate Limit All Requests
This example shows you how to rate limit all requests matching the HTTPRoute rule at 3 requests/Hour by leaving the `clientSelectors` field unset.
@@ -654,8 +694,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -679,8 +719,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -810,10 +850,10 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
- name: http-ratelimit
+ name: http-ratelimit
rateLimit:
type: Global
global:
@@ -859,10 +899,10 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
- name: http-ratelimit
+ name: http-ratelimit
rateLimit:
type: Global
global:
@@ -870,7 +910,7 @@ spec:
- clientSelectors:
- sourceCIDR:
value: 0.0.0.0/0
- type: distinct
+ type: Distinct
limit:
requests: 3
unit: Hour
@@ -950,8 +990,8 @@ kind: SecurityPolicy
metadata:
name: jwt-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: example
jwt:
@@ -968,8 +1008,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: example
rateLimit:
@@ -1018,8 +1058,8 @@ kind: SecurityPolicy
metadata:
name: jwt-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: example
jwt:
@@ -1036,8 +1076,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: example
rateLimit:
@@ -1080,11 +1120,11 @@ spec:
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
```shell
-TOKEN1=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/with-different-claim.jwt -s) && echo "$TOKEN1" | cut -d '.' -f2 - | base64 --decode -
+TOKEN1=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/with-different-claim.jwt -s) && echo "$TOKEN1" | cut -d '.' -f2 - | base64 --decode
```
### Rate limit by carrying `TOKEN`
@@ -1287,11 +1327,7 @@ data:
{{% /tab %}}
{{< /tabpane >}}
-* After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in
-
-```shell
-kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
-```
+{{< boilerplate rollout-envoy-gateway >}}
[Global Rate Limiting]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/global_rate_limiting
[Local rate limiting]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/local_rate_limiting
diff --git a/site/content/en/latest/tasks/traffic/http-request-headers.md b/site/content/en/latest/tasks/traffic/http-request-headers.md
index 9cd60281cdf..5b73bfaf8d3 100644
--- a/site/content/en/latest/tasks/traffic/http-request-headers.md
+++ b/site/content/en/latest/tasks/traffic/http-request-headers.md
@@ -442,7 +442,179 @@ spec:
{{% /tab %}}
{{< /tabpane >}}
+## Early Header Modification
+
+In some cases, it could be necessary to modify headers before the proxy performs any sort of processing, routing or tracing. Envoy Gateway supports this functionality using the [ClientTrafficPolicy][] API.
+
+A ClientTrafficPolicy resource can be attached to a Gateway resource to configure early header modifications for all its routes. In the following example we will demonstrate how early header modification can be configured.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+Querying `headers.example/get` should result in a `200` response from the example Gateway and the output from the
+example app should indicate that the upstream example app received the following headers:
+- `early-added-header` contains early (ClientTrafficPolicy) and late (RouteFilter) values
+- `early-set-header` contains only early (ClientTrafficPolicy) and late (RouteFilter) values, since the early modification overwritten the client value.
+- `early-removed-header` contains only the late (RouteFilter) value, since the early modification deleted the client value.
+
+```console
+$ curl -vvv --header "Host: headers.example" "http://${GATEWAY_HOST}/get" --header "early-added-header: client" --header "early-set-header: client" --header "early-removed-header: client"
+...
+> GET /get HTTP/1.1
+> Host: headers.example
+> User-Agent: curl/7.81.0
+> Accept: */*
+> add-header: something
+>
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< content-length: 474
+< x-envoy-upstream-service-time: 0
+< server: envoy
+<
+
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "Early-Added-Header": [
+ "client",
+ "early",
+ "late"
+ ],
+ "Early-Set-Header": [
+ "early",
+ "late"
+ ],
+ "Early-removed-Header": [
+ "late"
+ ]
+...
+```
+
[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/
[HTTPRoute filters]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter
[Gateway API documentation]: https://gateway-api.sigs.k8s.io/
[req_filter]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPHeaderFilter
+[ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy
diff --git a/site/content/en/latest/tasks/traffic/http-routing.md b/site/content/en/latest/tasks/traffic/http-routing.md
index 705846c6ec9..bb9eba88157 100644
--- a/site/content/en/latest/tasks/traffic/http-routing.md
+++ b/site/content/en/latest/tasks/traffic/http-routing.md
@@ -140,10 +140,10 @@ kind: SecurityPolicy
metadata:
name: jwt-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: jwt-claim-routing
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: jwt-claim-routing
jwt:
providers:
- name: example
@@ -208,10 +208,10 @@ kind: SecurityPolicy
metadata:
name: jwt-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: jwt-claim-routing
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: jwt-claim-routing
jwt:
providers:
- name: example
@@ -270,7 +270,7 @@ spec:
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
Test routing to the `foo-svc` backend by specifying a JWT Token with a claim `name: John Doe`.
@@ -283,7 +283,7 @@ curl -sS -H "Host: foo.example.com" -H "Authorization: Bearer $TOKEN" "http://${
Get another JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/with-different-claim.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/with-different-claim.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
Test HTTP routing to the `bar-svc` backend by specifying a JWT Token with a claim `name: Tom`.
diff --git a/site/content/en/latest/tasks/traffic/http-urlrewrite.md b/site/content/en/latest/tasks/traffic/http-urlrewrite.md
index 67915f93fcf..3515bd9caa4 100644
--- a/site/content/en/latest/tasks/traffic/http-urlrewrite.md
+++ b/site/content/en/latest/tasks/traffic/http-urlrewrite.md
@@ -275,6 +275,160 @@ $ curl -L -vvv --header "Host: path.rewrite.example" "http://${GATEWAY_HOST}/get
You can see that the `X-Envoy-Original-Path` is `/get/origin/path/extra`, but the actual path is
`/force/replace/fullpath`.
+## Rewrite URL Path with Regex
+
+In addition to core Gateway-API rewrite options, Envoy Gateway supports extended rewrite options through the [HTTPRouteFilter][] API.
+The `HTTPRouteFilter` API can be configured to use [RE2][]-compatible regex matchers and substitutions to rewrite a portion of the url.
+In the example below, requests sent to `http://${GATEWAY_HOST}/service/xxx/yyy` (where `xxx` is a single path portion and `yyy` is one or more path portions)
+are rewritten to `http://${GATEWAY_HOST}/yyy/instance/xxx`. The entire path is matched and rewritten using capture groups.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway.
+
+```shell
+kubectl get httproute/http-filter-url-regex-rewrite -o yaml
+```
+
+Querying `http://${GATEWAY_HOST}/service/foo/v1/api` should rewrite the request to
+`http://${GATEWAY_HOST}/service/foo/v1/api`.
+
+```console
+$ curl -L -vvv --header "Host: path.regex.rewrite.example" "http://${GATEWAY_HOST}/service/foo/v1/api"
+...
+> GET /service/foo/v1/api HTTP/1.1
+> Host: path.regex.rewrite.example
+> User-Agent: curl/8.7.1
+> Accept: */*
+>
+* Request completely sent off
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< date: Mon, 16 Sep 2024 18:49:48 GMT
+< content-length: 482
+<
+{
+ "path": "/v1/api/instance/foo",
+ "host": "path.regex.rewrite.example",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/8.7.1"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "10.244.0.37"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "24a5958f-1bfa-4694-a9c1-807d5139a18a"
+ ]
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-765694d47f-lzmpm"
+...
+```
+
+You can see that the path is rewritten from `/service/foo/v1/api`, to `/v1/api/instance/foo`.
+
## Rewrite Host Name
You can configure to rewrite the hostname like below. In this example, any requests sent to
@@ -401,4 +555,145 @@ $ curl -L -vvv --header "Host: path.rewrite.example" "http://${GATEWAY_HOST}/get
You can see that the `X-Forwarded-Host` is `path.rewrite.example`, but the actual host is `envoygateway.io`.
+## Rewrite URL Host Name by Header or Backend
+
+In addition to core Gateway-API rewrite options, Envoy Gateway supports extended rewrite options through the [HTTPRouteFilter][] API.
+The `HTTPRouteFilter` API can be configured to rewrite the Host header value to:
+- The value of a different request header
+- The DNS name of the backend that the request is routed to
+
+In the following example, the host header is rewritten to the value of the x-custom-host header.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway.
+
+```shell
+kubectl get httproute/http-filter-header-host-rewrite -o yaml
+```
+
+Querying `http://${GATEWAY_HOST}/header` and providing a custom host rewrite header x-custom-host should rewrite the
+request host header to the value of the x-custom-host header.
+
+```console
+$ curl -L -vvv --header "Host: host.header.rewrite.example" --header "x-custom-host: foo" "http://${GATEWAY_HOST}/header"
+...
+> GET /header HTTP/1.1
+> Host: host.header.rewrite.example
+> User-Agent: curl/8.7.1
+> Accept: */*
+> x-custom-host: foo
+>
+* Request completely sent off
+< HTTP/1.1 200 OK
+<
+{
+ "path": "/header",
+ "host": "foo",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "X-Custom-Host": [
+ "foo"
+ ],
+ "X-Forwarded-Host": [
+ "host.header.rewrite.example"
+ ],
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-765694d47f-5t6f2"
+...
+```
+
+You can see that the host is rewritten from `host.header.rewrite.example`, to the value of the provided
+`x-custom-host` header `foo`. The original host header is preserved in the `X-Forwarded-Host` header.
+
+
[HTTPURLRewriteFilter]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPURLRewriteFilter
+[HTTPRouteFilter]: ../../../api/extension_types#httproutefilter
+[RE2]: https://github.com/google/re2/wiki/Syntax
\ No newline at end of file
diff --git a/site/content/en/latest/tasks/traffic/http3.md b/site/content/en/latest/tasks/traffic/http3.md
index cb5034284c1..a0fb1594295 100644
--- a/site/content/en/latest/tasks/traffic/http3.md
+++ b/site/content/en/latest/tasks/traffic/http3.md
@@ -69,10 +69,10 @@ metadata:
name: enable-http3
spec:
http3: {}
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
EOF
```
@@ -88,10 +88,10 @@ metadata:
name: enable-http3
spec:
http3: {}
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
```
{{% /tab %}}
diff --git a/site/content/en/latest/tasks/traffic/load-balancing.md b/site/content/en/latest/tasks/traffic/load-balancing.md
index b8bdff01af2..3c9a78450b5 100644
--- a/site/content/en/latest/tasks/traffic/load-balancing.md
+++ b/site/content/en/latest/tasks/traffic/load-balancing.md
@@ -13,7 +13,7 @@ Envoy Gateway supports the following load balancing policies:
- **Consistent Hash**: load balancer implements consistent hashing to upstream hosts.
Envoy Gateway introduces a new CRD called [BackendTrafficPolicy][] that allows the user to describe their desired load balancing polices.
-This instantiated resource can be linked to a [Gateway][], [HTTPRoute][] or [GRPCRoute][] resource.
+This instantiated resource can be linked to a [Gateway][], [HTTPRoute][] or [GRPCRoute][] resource. If `loadBalancer` is not specified in [BackendTrafficPolicy][], the default load balancing policy is `Least Request`.
## Prerequisites
diff --git a/site/content/en/latest/tasks/traffic/local-rate-limit.md b/site/content/en/latest/tasks/traffic/local-rate-limit.md
index a7b920db1c4..05caf07258c 100644
--- a/site/content/en/latest/tasks/traffic/local-rate-limit.md
+++ b/site/content/en/latest/tasks/traffic/local-rate-limit.md
@@ -43,8 +43,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -72,8 +72,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -245,6 +245,227 @@ server: envoy
```
+## Rate Limit Specific User Unless within Test Org
+
+Here is an example of a rate limit implemented by the application developer to limit a specific user by matching on a custom `x-user-id` header
+with a value set to `one`. But the user must not be limited if logging in within Test org, determined by custom header `x-org-id` set to `test`.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+### HTTPRoute
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway.
+
+```shell
+kubectl get httproute/http-ratelimit -o yaml
+```
+
+Get the Gateway's address:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+Let's query `ratelimit.example/get` 4 times with `x-user-id` set to `one` and `x-org-id` set to `org1`. We should receive a `200` response from the example Gateway for the first 3 requests and the last request should be rate limited.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: one" --header "x-org-id: org1" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 429 Too Many Requests
+x-envoy-ratelimited: true
+date: Wed, 08 Feb 2023 02:33:34 GMT
+server: envoy
+transfer-encoding: chunked
+
+```
+
+Let's query `ratelimit.example/get` 4 times with `x-user-id` set to `one` and `x-org-id` set to `test`. We should receive a `200` response from the example Gateway for all the 4 requests, unlike previous example where the last request was rate limited.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: one" --header "x-org-id: test" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+```
+
## Rate Limit All Requests
This example shows you how to rate limit all requests matching the HTTPRoute rule at 3 requests/Hour by leaving the `clientSelectors` field unset.
@@ -259,8 +480,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -284,8 +505,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
diff --git a/site/content/en/latest/tasks/traffic/response-override.md b/site/content/en/latest/tasks/traffic/response-override.md
new file mode 100644
index 00000000000..ea8121bfe89
--- /dev/null
+++ b/site/content/en/latest/tasks/traffic/response-override.md
@@ -0,0 +1,157 @@
+---
+title: "Response Override"
+---
+
+Response Override allows you to override the response from the backend with a custom one. This can be useful for scenarios such as returning a custom 404 page when the requested resource is not found or a custom 500 error message when the backend is failing.
+
+## Installation
+
+Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+## Testing Response Override
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/status/404
+```
+
+```console
+* Trying 127.0.0.1:80...
+* Connected to 172.18.0.200 (172.18.0.200) port 80
+> GET /status/404 HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.5.0
+> Accept: */*
+>
+< HTTP/1.1 404 Not Found
+< content-type: text/plain
+< content-length: 32
+< date: Thu, 07 Nov 2024 09:22:29 GMT
+<
+* Connection #0 to host 172.18.0.200 left intact
+Oops! Your request is not found.
+```
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/status/500
+```
+
+```console
+* Trying 127.0.0.1:80...
+* Connected to 172.18.0.200 (172.18.0.200) port 80
+> GET /status/500 HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.5.0
+> Accept: */*
+>
+< HTTP/1.1 500 Internal Server Error
+< content-type: application/json
+< content-length: 34
+< date: Thu, 07 Nov 2024 09:23:02 GMT
+<
+* Connection #0 to host 172.18.0.200 left intact
+{"error": "Internal Server Error"}
+```
\ No newline at end of file
diff --git a/site/content/en/latest/tasks/traffic/retry.md b/site/content/en/latest/tasks/traffic/retry.md
index 25b7e2519ec..75d151bdff6 100644
--- a/site/content/en/latest/tasks/traffic/retry.md
+++ b/site/content/en/latest/tasks/traffic/retry.md
@@ -56,10 +56,10 @@ kind: BackendTrafficPolicy
metadata:
name: retry-for-route
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
retry:
numRetries: 5
perRetry:
@@ -87,10 +87,10 @@ kind: BackendTrafficPolicy
metadata:
name: retry-for-route
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
retry:
numRetries: 5
perRetry:
diff --git a/site/content/en/news/releases/_index.md b/site/content/en/news/releases/_index.md
index cff55283750..3be0024984b 100644
--- a/site/content/en/news/releases/_index.md
+++ b/site/content/en/news/releases/_index.md
@@ -8,8 +8,7 @@ type = "docs"
+++
This document provides details for Envoy Gateway releases. Envoy Gateway follows the Semantic Versioning [v2.0.0 spec][]
-for release versioning. Since Envoy Gateway is a new project, minor releases are the only defined releases. Envoy
-Gateway maintainers will establish additional release details, e.g. patch releases, at a future date.
+for release versioning.
## Stable Releases
@@ -32,10 +31,12 @@ communications with the Envoy Gateway community, and the mechanics of the releas
|:-------:|:--------------------------------------------------------------:|
| 2022 Q4 | Daneyon Hansen ([danehans](https://github.com/danehans)) |
| 2023 Q1 | Xunzhuo Liu ([Xunzhuo](https://github.com/Xunzhuo)) |
-| 2023 Q2 | Alice Wasko ([AliceProxy](https://github.com/AliceProxy)) |
+| 2023 Q2 | Alice Wasko ([Alice-Lilith](https://github.com/Alice-Lilith)) |
| 2023 Q3 | Arko Dasgupta ([arkodg](https://github.com/arkodg)) |
| 2023 Q4 | Arko Dasgupta ([arkodg](https://github.com/arkodg)) |
| 2024 Q1 | Xunzhuo Liu ([Xunzhuo](https://github.com/Xunzhuo)) |
+| 2024 Q3 | Guy Daich ([guydc](https://github.com/guydc)) |
+| 2024 Q4 | Huabing Zhao ([zhaohuabing](https://github.com/zhaohuabing))|
## Release Schedule
@@ -49,6 +50,9 @@ In order to align with the Envoy Proxy [release schedule][], Envoy Gateway relea
| 0.4.0 | 2023/04/22 | 2023/04/24 | +2 days | 2023/10/24 |
| 0.5.0 | 2023/07/22 | 2023/08/02 | +10 days | 2024/01/02 |
| 0.6.0 | 2023/10/22 | 2023/11/02 | +10 days | 2024/05/02 |
+| 1.0.x | 2024/03/06 | 2023/03/13 | +7 days | 2024/09/13 |
+| 1.1.x | 2024/07/16 | 2024/07/22 | +6 days | 2024/01/22 |
+| 1.2.x | 2024/10/22 | 2024/11/06 | +14 days | 2025/05/06 |
[v2.0.0 spec]: https://semver.org/spec/v2.0.0.html
[release guide]: ../../contributions/releasing
diff --git a/site/content/en/news/releases/matrix.md b/site/content/en/news/releases/matrix.md
index 337b26d1262..d798d85fb40 100644
--- a/site/content/en/news/releases/matrix.md
+++ b/site/content/en/news/releases/matrix.md
@@ -7,6 +7,8 @@ Envoy Gateway relies on the Envoy Proxy and the Gateway API, and runs within a K
| Envoy Gateway version | Envoy Proxy version | Rate Limit version | Gateway API version | Kubernetes version |
|-----------------------|-----------------------------|--------------------|---------------------|----------------------------|
+| latest | **dev-latest** | **master** | **v1.2.0** | v1.29, v1.30, v1.31, v1.32 |
+| v1.2 | **distroless-v1.32.1** | **28b1629a** | **v1.2.0** | v1.28, v1.29, v1.30, v1.31 |
| v1.1 | **distroless-v1.31.0** | **91484c59** | **v1.1.0** | v1.27, v1.28, v1.29, v1.30 |
| v1.0 | **distroless-v1.29.2** | **19f2079f** | **v1.0.0** | v1.26, v1.27, v1.28, v1.29 |
| v0.6 | **distroless-v1.28-latest** | **b9796237** | **v1.0.0** | v1.26, v1.27, v1.28 |
@@ -14,4 +16,3 @@ Envoy Gateway relies on the Envoy Proxy and the Gateway API, and runs within a K
| v0.4 | **v1.26-latest** | **542a6047** | **v0.6.2** | v1.25, v1.26, v1.27 |
| v0.3 | **v1.25-latest** | **f28024e3** | **v0.6.1** | v1.24, v1.25, v1.26 |
| v0.2 | **v1.23-latest** | | **v0.5.1** | v1.24 |
-| latest | **dev-latest** | **master** | **v1.0.0** | v1.27, v1.28, v1.29, v1.30 |
diff --git a/site/content/en/news/releases/notes/v1.1.1.md b/site/content/en/news/releases/notes/v1.1.1.md
new file mode 100644
index 00000000000..5f5cda1c142
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.1.1.md
@@ -0,0 +1,35 @@
+---
+title: "v1.1.1"
+publishdate: 2024-09-11
+---
+
+Date: September 11, 2024
+
+## Documentation
+- Bumped Golang version to 1.22.7
+
+## Conformance
+- Enabled GatewayHTTPListenerIsolation test
+
+## Testing
+- Fix download URL of envoy proxy WASM examples used in tests
+
+## Translator
+- Fixed url rewrite to remove trailing slash
+- Isolate HTTP route tables to listener according to Gateway-API specifications
+- Fixed identification of ReferenceGrant when multiple ReferenceGrants exist in a namespace
+- Fixed added header values as a command and space delimited list
+- Fixed assertion on expected status in active HTTP healthcheck
+- Fixed rejection of invalid Backends referenced by xRoutes
+- Fixed support for empty SlowStart configuration when using LeastRequest loadbalancing
+- Fixed update of status for Backends
+
+## Infra-manager
+- Pin ratelimit version to 26f28d78
+- Reduce readinessProbe failureThreshold and periodSeconds of proxy
+- Expose ratelimit statsd
+
+## Providers
+- Fixed error returned when referenced Configmap or Secret is not found
+- Use component name in Envoy Gateway logs
+
diff --git a/site/content/en/news/releases/notes/v1.1.2.md b/site/content/en/news/releases/notes/v1.1.2.md
new file mode 100644
index 00000000000..b47371addce
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.1.2.md
@@ -0,0 +1,17 @@
+---
+title: "v1.1.2"
+publishdate: 2024-09-24
+---
+
+Date: September 24, 2024
+
+## Translator
+- Fixed handling of sectionName in BackendTLSPolicy for Backend resource
+
+## Infra-manager
+- Pin Envoy Proxy version to v1.32.2
+- Change Envoy listener drain strategy from gradual to immediate
+
+## Providers
+- Fixed reconciliation of HTTPRoutes when labels change
+
diff --git a/site/content/en/news/releases/notes/v1.1.3.md b/site/content/en/news/releases/notes/v1.1.3.md
new file mode 100644
index 00000000000..97128c1cc6c
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.1.3.md
@@ -0,0 +1,31 @@
+---
+title: "v1.1.3"
+publishdate: 2024-11-01
+---
+
+Date: November 1, 2024
+
+## Breaking changes
+-
+
+## New features
+-
+
+## Bug fixes
+- Fixed unsupported listener protocol type causing an error while updating Gateway Status
+- Fixed some status updates were being discarded by the status updater
+- Fixed error level logging for admin and metrics modules
+- Fixed Dashboard typos
+- Fixed Ratelimit Deployment ignoring pod labels and annotation merge
+- Fixed the API Server receives unnecessary requests
+- Fixed set invalid Listener.SupportedKinds to empty list
+- Fixed losing timeout settings that originate from the route when translating the backend traffic policy
+- Fixed xds translation failure when wasm http code source configured without sha
+
+## Performance improvements
+-
+
+## Other changes
+- Bumped Envoy proxy to 1.31.3
+- Bumped github.com/docker/docker to 27.3.1+incompatible
+
diff --git a/site/content/en/news/releases/notes/v1.1.4.md b/site/content/en/news/releases/notes/v1.1.4.md
new file mode 100644
index 00000000000..338e5f833db
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.1.4.md
@@ -0,0 +1,19 @@
+---
+title: "v1.1.4"
+publishdate: 2024-12-12
+---
+
+Date: December 12, 2024
+
+## Bug fixes
+- Fixed validate proto messages before converting them to anypb.Any
+- Fixed BackendTlsPolicy specify multiple targetRefs of the same service, only one will work
+- Fixed Envoy rejecting TCP Listeners that have no attached TCPRoutes
+- Fixed frequent 503 errors when connecting to a Service experiencing high Pod churn
+- Fixed reference grant from EnvoyExtensionPolicy to referenced ext-proc backend not respected
+- Fixed BackendTrafficPolicy not applying to Gateway Route when Route has a Request Timeout defined
+
+## Other changes
+- Bumped Rate Limit to 49af5cca
+- Bumped golang.org/x/crypto to 0.31.0
+
diff --git a/site/content/en/news/releases/notes/v1.2.0-rc.1.md b/site/content/en/news/releases/notes/v1.2.0-rc.1.md
new file mode 100644
index 00000000000..cfdfe12d27f
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.2.0-rc.1.md
@@ -0,0 +1,133 @@
+---
+title: "v1.2.0-rc.1"
+publishdate: 2024-10-25
+---
+
+Date: October 25, 2024
+
+## Breaking changes
+- Gateway API GRPCRoute and ReferenceGrant v1alpha2 have been removed.
+- Please refer to the [Gateway API v1.2.0 documentation](https://github.com/kubernetes-sigs/gateway-api/releases) for more information.
+- Removed default CPU limit of the Envoy Gateway deployment
+- Changed default Envoy shutdown settings: drain strategy has been changed to immediate, default minDrainDuration, drainTimeout and terminationGracePeriodSeconds have been set to 10s, 60s and 360s respectively
+
+## New features
+- Added support for Gateway-API v1.2.0
+- Added support for IPv4/IPv6 Dual Stack for Envoy listeners and BackendRef resources
+- Added support for EG standalone(host deployment) mode (experimental)
+- Added support for JWT claims based Authorization in SecurityPolicy CRD
+- Added support for Direct Response in HTTPRouteFilter CRD
+- Added support for Response Override in BackendTrafficPolicy CRD
+- Added support for RequestTimeout in BackendTrafficPolicy CRD
+- Added support for inverting header matches for rate limit in BackendTrafficPolicy CRD
+- Added support for client TLS session resumption in ClientTrafficPolicy CRD
+- Added support for HTTPRouteFilter and path regex rewrite
+- Added support for host header rewrite in HTTPRouteFilter CRD
+- Added support for Listener Access Log in EnvoyProxy CRD
+- Added support for Datadog tracing support in EnvoyProxy CRD
+- Added support for request response sizes stats in EnvoyProxy CRD
+- Added support for wildcard matching for CORS AllowMethods and AllowHeaders settings in SecurityPolicy CRD
+- Added support for match conditions for access log in EnvoyProxy CRD
+- Added support for using BackendCluster to represent OIDCProvider
+- Added support for RecomputeRoute for ExtAuth in SecurityPolicy CRD
+- Added support for sharing token cookies between multiple domains in SecurityPolicy CRD
+- Added support for JSONPatches for proxy bootstrap modifications in EnvoyProxy CRD
+- Added support for LB priority for non xRoute endpoints
+- Added support for configuring the GRPC Health Checker in the BackendTrafficPolicy CRD
+- Added support for early request header mutation in the ClientTrafficPolicy CRD
+- Added support for JsonPath in the EnvoyPatchPolicy CRD
+- Added support for cluster settings for tracing and access log backends in EnvoyProxy CRD
+- Added support for cluster settings for non xRoute-generated backend refs
+- Added support for socket buffer limit field in ClientTrafficPolicy and BackendTrafficPolicy CRD
+- Added support for http2 upstream settings in BackendTrafficPolicy CRD
+- Added support for DNS resolution settings in BackendTrafficPolicy CRD
+- Added support for configuring service annotations in the Envoy Gateway helm chart
+- Added support for configuring priorityClassName to Envoy Gateway helm chart
+- Added support for ratelimit metrics monitoring in grafana in the addons helm chart
+- Added support for default user group and user id for the SecurityContexts in the Envoy Gateway helm chart
+- Added support for maxUnavailable in the PodDisruptionBudget in the Envoy Gateway helm chart
+- Added support for configuring NodeSelector in the Envoy Gateway helm chart
+- Added support for nonce in the OIDC auth flow
+- Added support for choosing an HTTPRoute's non-wildcard hostname as the default Host
+- Added support for returning 500 when EnvoyExtensionTrafficPolicy translation fails
+- Added support for returning 500 when SecurityPolicy translation fails
+- Added support for multiple backendRefs for ExtAuth and ExtProc
+- Added support for session persistence in HTTPRoute rules
+- Added support for the Backend resource for ExtAuth
+- Added support for target selectors on Envoy Gateway Extension Server policies
+- Added support for non-Kubernetes Backends for TLSRoute
+- Added support for fallback to the Backend API
+- Added support for reloadable EnvoyGateway configuration
+- Added support for adding Labels to the Envoy Service
+- Added support for custom name for ratelimit deployment
+- Added default SecurityContext for EG components
+- Added startupProbe to all provisioned containers
+- Added support for local validations for egctl translate and file provider
+- Added support for egctl x collect to collect information from the cluster for debugging
+- Added support for a native prometheus metrics endpoint in the ratelimit server
+
+## Bug fixes
+- Fixed unsupported listener protocol type causing an error while updating Gateway Status
+- Fixed some status updates were being discarded by the status updater
+- Fixed Gateway crash adding BackendTLSPolicy to External Backend of an HTTPRoute
+- Fixed Delay in SecurityPolicy change propagation for HTTPRoute when using targetSelectors
+- Fixed JSONPath not correctly translated to JSONPatch paths
+- Fixed allow empty slowStart when using LeastRequest
+- Fixed Backends which should be rejected are still used as an HTTPRoute's destination
+- Fixed losing timeout settings that originate from the route when translating the backend traffic policy
+- Fixed Backend resources don't get status updates
+- Fixed Active Health check requires expectedStatuses field to work
+- Fixed HTTPHeaderFilter processing doesn't correctly support multiple header values
+- Fixed multiple reference grants in same namespace
+- Fixed upstream get unwanted /.
+- Fixed creation of SecurityPolicy with targetSelectors fails
+- Fixed wrong gateway is chosen as HTTPRoute parent
+- Fixed override issue for EEP
+- Fixed nil pointer err translating hash load balancing
+- Fixed ratelimit does not work across multiple GatewayClasses
+- Fixed upstream mTLS only works for HTTPS listeners
+- Fixed nil pointer if backedtls.minVersion is set but backedtls.maxVersion is not
+- Fixed empty connection limit causes XDS rejection
+- Fixed ratelimit not working with both headers and cidr matches
+- Fixed EDS didn't update when deployments was created after services
+- Fixed RBAC issue for deleting infrastructure resources
+- Fixed customized infrastructure resources not being deleted
+- Fixed Gateways never become ready/programmed when running Envoy as a Daemonset
+- Fixed Ratelimit Deployment ignoring pod labels and annotation merge
+- Fixed the API Server receives unnecessary requests
+- Fixed terminating envoy pods don't respond with "Connection: close" (H1) or GOAWAY(H2) on shutdown, switch to an immediate drain strategy
+- Fixed ratelimit statsd not working
+- Fixed not generating selector of deployment/daemonset based on the custom label configuration of EnvoyProxy
+- Fixed egctl experimental translate using a wrong ns
+
+## Performance improvements
+- Fixed repeated resources and optimize memory usage
+
+## Other changes
+- Removed grafana test framework from the addons helm chart
+- Disabled ALPN for non-HTTP routes
+- Added statPrefix for HCM and TCPProxy
+- Enabled GatewayHTTPListenerIsolation conformance test
+- Enabled GRPC conformance profile
+- Enabled HTTPRouteBackendRequestHeaderModifier conformance test
+- Added e2e test for Daemonset mode
+- Updated upgrades tests to use VERSION env variable
+- Fixed OVS scanner wrong license warnings
+- Added e2e test for TLS session resumption
+- Added heap profile into benchmark report
+- Added e2e test for RecomputeRoute in ExtAuth
+- Added benchmark memory profiles into report
+- Fixed flaky gateway_with_conflicted_listener_cannot_be_merged e2e test
+- Fixed flaky Zipkin Tracing e2e test
+- Added e2e test for cookie based consistent hash load balancing
+- Added e2e test for load balancing
+- Fixed flaky authorization tests
+- Enabled upgrade test
+- Fixed flaky basic auth e2e test
+- Enabled use-client-protocol e2e test
+- Added performance benchmarking test for 1000 HTTPRoutes
+- Added e2e test for Datadog tracing
+- Added e2e tests for ratelimit invert matching headers
+- Reduced readinessProbe failureThreshold and periodSeconds
+- Bumped go-control-plane to v0.13.1
+
diff --git a/site/content/en/news/releases/notes/v1.2.0.md b/site/content/en/news/releases/notes/v1.2.0.md
new file mode 100644
index 00000000000..29c00593b3e
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.2.0.md
@@ -0,0 +1,144 @@
+---
+title: "v1.2.0"
+publishdate: 2024-11-06
+---
+
+Date: November 06, 2024
+
+## Breaking Changes
+- Gateway API GRPCRoute and ReferenceGrant v1alpha2 have been removed
+- Please refer to the [Gateway API v1.2.0 documentation](https://github.com/kubernetes-sigs/gateway-api/releases) for more information
+- Removed default CPU limit of the Envoy Gateway deployment, to eliminate CPU throttling
+- Changed default Envoy shutdown settings: drain strategy has been changed to immediate, default minDrainDuration, drainTimeout and terminationGracePeriodSeconds have been set to 10s, 60s and 360s respectively
+- Set `ignore_health_on_host_removal` to true for clusters with static endpoints This was done to speed up removal of static endpoints by the control plane when active health check is configured
+- Xds and Infra IR logs are logged at Debug level instead of Info level. They will now not be seen by default in Envoy Gateway logs. You can change the logging level to `default: debug` to view them
+
+## New Features
+- Added support for Gateway-API v1.2.0
+- Added support for IPv4/IPv6 Dual Stack for EnvoyProxy fleet and BackendRef resources
+- Added experimental support for EG standalone(host deployment) mode
+- Added support for JWT claims based Authorization in SecurityPolicy CRD
+- Added support for Response Override in BackendTrafficPolicy CRD
+- Added support for RequestTimeout in BackendTrafficPolicy CRD
+- Added support for inverting header matches for Rate Limit in BackendTrafficPolicy CRD
+- Added support for client TLS session resumption in ClientTrafficPolicy CRD
+- Added support for HTTPRouteFilter and path regex rewrite
+- Added support for host header rewrite in HTTPRouteFilter CRD
+- Added support for Listener Access Log in EnvoyProxy CRD
+- Added support for Datadog tracing support in EnvoyProxy CRD
+- Added support for request response sizes stats in EnvoyProxy CRD
+- Added support for modifying container SecurityContext for Envoy Gateway deployment in Helm
+- Added support for wildcard matching for CORS AllowMethods and AllowHeaders settings in SecurityPolicy CRD
+- Added support for match conditions for access log in EnvoyProxy CRD
+- Added support for using BackendCluster to represent OIDCProvider
+- Added support for RecomputeRoute for ExtAuth in SecurityPolicy CRD
+- Added support for sharing token cookies between multiple domains in SecurityPolicy CRD
+- Added support for JSONPatches for proxy bootstrap modifications in EnvoyProxy CRD
+- Added support for Active Passive Failover Backends
+- Added support for configuring the GRPC Health Checker in the BackendTrafficPolicy CRD
+- Added support for early request header mutation in the ClientTrafficPolicy CRD
+- Added support for JsonPath in the EnvoyPatchPolicy CRD
+- Added support for cluster settings for tracing and access log backends in EnvoyProxy CRD
+- Added support for cluster settings for non xRoute-generated backend refs
+- Added support for socket buffer limit field in ClientTrafficPolicy and BackendTrafficPolicy CRD
+- Added support for http2 upstream settings in BackendTrafficPolicy CRD
+- Added support for DNS resolution settings in BackendTrafficPolicy CRD
+- Added support for configuring service annotations in the Envoy Gateway helm chart
+- Added support for configuring priorityClassName to Envoy Gateway helm chart
+- Added support for ratelimit metrics monitoring in grafana in the addons helm chart
+- Added support for default user group and user id for the SecurityContexts in the Envoy Gateway helm chart
+- Added support for maxUnavailable in the PodDisruptionBudget in the Envoy Gateway helm chart
+- Added support for configuring NodeSelector in the Envoy Gateway helm chart
+- Added support for nonce in the OIDC auth flow
+- Added support for choosing an HTTPRoute's non-wildcard hostname as the default Host
+- Added support for returning 500 when EnvoyExtensionTrafficPolicy translation fails
+- Added support for returning 500 when SecurityPolicy translation fails
+- Added support for multiple backendRefs for ExtAuth and ExtProc
+- Added support for session persistence in HTTPRoute rules
+- Added support for the Backend resource for ExtAuth
+- Added support for target selectors on Envoy Gateway Extension Server policies
+- Added support for non-Kubernetes Backends for TLSRoute
+- Added support for fallback to the Backend API
+- Added support for reloadable EnvoyGateway configuration
+- Added support for adding Labels to the Envoy Service
+- Added support for custom name for ratelimit deployment
+- Added default SecurityContext for EG components
+- Added startupProbe to all provisioned containers
+- Added support for local validations for egctl translate and file provider
+- Added support for egctl x collect to collect information from the cluster for debugging
+- Added support for a native prometheus metrics endpoint in the ratelimit server
+
+## Bug Fixes
+- Fixed xDS translation failing when the WASM HTTP code source was configured without an SHA
+- Fixed unsupported listener protocol types causing errors while updating Gateway status
+- Fixed unsupported listener protocol types causing errors while updating Gateway status
+- Fixed invalid sectionName in BackendTLSPolicy for Backend
+- Fixed Delay in SecurityPolicy change propagation for HTTPRoute when using targetSelectors
+- Fixed JSONPath not being correctly translated to JSONPatch paths
+- Fixed allowing an empty slowStart value when using LeastRequest
+- Fixed updating the HTTPRoute status correctly when the linked Backend resource is invalid
+- Fixed timeout settings originating from the route being lost when translating the backend traffic policy
+- Fixed Backend resources not receiving status updates
+- Fixed active health checks requiring the expectedStatuses field to function correctly
+- Fixed HTTPHeaderFilter processing not correctly supporting multiple header values
+- Fixed reconciling multiple ReferenceGrants within the same namespace
+- Fixed unwanted / appearing in the Path when using Prefix Rewrites
+- Fixed incorrect gateway being selected as the HTTPRoute parent
+- Fixed override issues for EnvoyExtensionPolicy
+- Fixed nil pointer error when translating hash load balancing
+- Fixed nil pointer if backedtls.minVersion is set but backedtls.maxVersion is not
+- Fixed empty connection limits causing xDS rejection
+- Fixed rate limiting not working with both headers and CIDR matches
+- Fixed EDS not updating when deployments were created after services
+- Fixed RBAC issue for deleting infrastructure resources
+- Fixed gateways never reaching ready/programmed status when running Envoy as a Daemonset
+- Fixed rate limit deployment ignoring pod labels and annotation merges
+- Fixed the API Server receives unnecessary requests
+- Fixed egctl experimental translate using an incorrect namespace
+- Fixed reconciliation not being triggered for Secret updates referenced by a BackendTLSPolicy
+- Fixed xDS translation failure when WASM HTTP code source was configured without an SHA
+- Fixed HTTPRoute status displaying only one parent when targeting multiple gateways from different GatewayClasses
+- Fixed Route with multiple parents having an incorrect namespace in the parentRef status
+- Fixed BackendTlsPolicy specifying multiple targetRefs for the same service, to work
+
+
+### Performance Improvements
+- Optimize memory usage by only storing distinct resources
+- SecurityPolicy translation failures will now cause routes referenced by the policy to return an immediate 500 response
+- Gateway-API BackendTLSPolicy v1alpha3 is incompatible with previous versions of the CRD
+- xPolicy targetRefs can no longer specify a namespace, since Gateway-API v1.1.0 uses LocalPolicyTargetReferenceWithSectionName in Policy resources
+
+### Other changes
+- Upgraded Envoy Proxy to v1.32.1
+- Reduced the amount of configuration logging, and make it line-delimited friendly
+- Made watching alpha CRDs optional, so that Envoy Gateway can run with older Gateway Api versions
+- Removed grafana test framework from the addons helm chart
+- Disabled ALPN for non-HTTP routes
+- Added statPrefix for HCM and TCPProxy
+- Enabled GatewayHTTPListenerIsolation conformance test
+- Enabled GRPC conformance profile
+- Enabled HTTPRouteBackendRequestHeaderModifier conformance test
+- Added e2e test for Daemonset mode
+- Fixed OVS scanner wrong license warnings
+- Added e2e test for Gateway with EnvoyProxy
+- Added e2e test for TLS session resumption
+- Added heap profile into benchmark report
+- Added e2e test for RecomputeRoute in ExtAuth
+- Added benchmark memory profiles into report
+- Fixed flaky gateway_with_conflicted_listener_cannot_be_merged e2e test
+- Fixed flaky Zipkin Tracing e2e test
+- Added e2e test for cookie based consistent hash load balancing
+- Added e2e test for load balancing
+- Fixed flaky authorization tests
+- Enabled upgrade test
+- Fixed flaky basic auth e2e test
+- Enabled use-client-protocol e2e test
+- Added performance benchmarking test for 1000 HTTPRoutes
+- Added e2e test for Datadog tracing
+- Added e2e tests for ratelimit invert matching headers
+- Reduced readinessProbe failureThreshold and periodSeconds
+- Bumped go-control-plane to v0.13.1
+- Enabled e2e tests for dual stack
+- Use grafana alloy instead of fluent-bit for e2e tests
+- Push tags without the v prefix for helm charts to support Flux HelmReleases
+- Use a stable label selector when creating Envoy Proxy fleet pods
diff --git a/site/content/en/news/releases/notes/v1.2.1.md b/site/content/en/news/releases/notes/v1.2.1.md
new file mode 100644
index 00000000000..991183eca78
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.2.1.md
@@ -0,0 +1,9 @@
+---
+title: "v1.2.1"
+publishdate: 2024-11-07
+---
+
+Date: November 7, 2024
+
+## Bug fixes
+- Fixed a panic in the provider goroutine when the body in the direct response configuration was nil.
diff --git a/site/content/en/news/releases/notes/v1.2.2.md b/site/content/en/news/releases/notes/v1.2.2.md
new file mode 100644
index 00000000000..2aba0440826
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.2.2.md
@@ -0,0 +1,17 @@
+---
+title: "v1.2.2"
+publishdate: 2024-11-28
+---
+
+Date: November 28, 2024
+
+## Bug fixes
+- Fixed Envoy rejecting TCP Listeners that have no attached TCPRoutes.
+- Fixed failed to update SecurityPolicy resources with the `backendRef` field specified.
+- Fixed xDS translation failed when oidc tokenEndpoint and jwt remoteJWKS are specified in the same SecurityPolicy and using the same hostname.
+- Fixed frequent 503 errors when connecting to a Service experiencing high Pod churn.
+
+## Other changes
+- Bump the RateLimit image to 49af5cca.
+- Always use `::` and `IPv4Compact` enabled on dynamic listeners.
+- Use `V4_PREFERRED` instead of `V4_ONLY` by default for the cluster's `DnsLookupFamily`.
diff --git a/site/content/en/news/releases/notes/v1.2.3.md b/site/content/en/news/releases/notes/v1.2.3.md
new file mode 100644
index 00000000000..1fc38d7088d
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.2.3.md
@@ -0,0 +1,14 @@
+---
+title: "v1.2.3"
+publishdate: 2024-12-02
+---
+
+Date: December 2, 2024
+
+## Bug fixes
+- Disabled the retry policy for the JWT provider to reduce requests sent to the JWKS endpoint. Failed async fetches will retry every 1s.
+- Used a waitGroup instead of an enabled channel in the status updater.
+
+## Other changes
+- EG Listens on IPv4 by default, but if IPFamily is set to IPv6 or DualStack, it listens on :: and enables ipv4_compat for DualStack.
+- Bumped Gateway API to v1.2.1.
diff --git a/site/content/en/news/releases/notes/v1.2.4.md b/site/content/en/news/releases/notes/v1.2.4.md
new file mode 100644
index 00000000000..6ec26d2c2e6
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.2.4.md
@@ -0,0 +1,16 @@
+---
+title: "v1.2.4"
+publishdate: 2024-12-13
+---
+
+Date: December 13, 2024
+
+## Bug fixes
+- Fixed BackendTLSPolicy not supporting the use of a port name as the sectionName in targetRefs.
+- Fixed reference grant from EnvoyExtensionPolicy to the referenced ext-proc backend not being respected.
+- Fixed BackendTrafficPolicy not applying to Gateway Routes when a Route has a Request Timeout defined.
+- Fixed proxies connected to the secondary Envoy Gateway not receiving xDS configuration.
+- Fixed traffic splitting not working when some backends were invalid.
+
+## Other changes
+- Bumped Envoy to version 1.32.2.
diff --git a/site/content/en/news/releases/v1.2.md b/site/content/en/news/releases/v1.2.md
new file mode 100644
index 00000000000..4c04b1dfcac
--- /dev/null
+++ b/site/content/en/news/releases/v1.2.md
@@ -0,0 +1,95 @@
+---
+title: Announcing Envoy Gateway v1.2
+subtitle: Minor Update
+linktitle: Release v1.2
+description: Envoy Gateway v1.2 release announcement.
+publishdate: 2024-11-06
+release: v1.2.0
+skip_list: true
+---
+
+We are thrilled to announce the arrival of Envoy Gateway v1.2.0.
+
+This release represents a significant achievement, and we extend our heartfelt gratitude to the entire Envoy Gateway community for their contributions, dedication, and support. Your collaborative efforts have been instrumental in reaching this pivotal release.
+
+Thank you for being an integral part of this journey. We are excited to see how Envoy Gateway v1.2.0 will empower your operations and look forward to continuing our work together to drive the future of Cloud Native API Gateway.
+
+| [Release Notes][] | [Docs][docs] | [Compatibility Matrix][matrix] | [Install][] |
+|-------------------|--------------|--------------------------------|--------------|
+
+## What's New
+
+The release adds a ton of features and functionality. Here are some highlights:
+
+---
+
+## 🚨 Breaking Changes
+
+- **Gateway API Updates**: Removed support for the v1alpha2 versions for `GRPCRoute` and `ReferenceGrant`. [See the Gateway API v1.2.0 documentation](https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.2.0) for details.
+- **CPU Limits**: Removed default CPU limit for Envoy Gateway deployment to avoid throttling.
+- **Envoy Shutdown Settings**: Drain strategy set to immediate, with default values as follows:
+ - `minDrainDuration`: 10s
+ - `drainTimeout`: 60s
+ - `terminationGracePeriodSeconds`: 360s
+- **Endpoint Health On Host Removal**: Enabled `ignore_health_on_host_removal` for clusters with static endpoints to allow faster removal of endpoints that have been deleted by the control plane, without waiting for the results of an active health check.
+- **Logging Level Adjustment**: Set xDS and Infra IR logs to Debug level instead of Info, so they will no longer appear in Envoy Gateway logs by default. You can change the logging level to `debug` to view them.
+
+---
+
+## ✨ New Features
+
+### API & Traffic Management Enhancements
+- **Gateway-API v1.2.0 Support**: Fully compatible with the latest Gateway-API standards.
+- **IPv4/IPv6 Dual Stack**: Now available for EnvoyProxy fleet and `BackendRef` resources.
+- **Standalone Mode**: Experimental support for Envoy Gateway standalone (host deployment) mode.
+- **Response Override**: Added support for `Response Override` and `RequestTimeout` in [BackendTrafficPolicy](https://gateway.envoyproxy.io/docs/api/extension_types/#backendtrafficpolicy).
+- **Active Passive Failover**: Supported with the new `fallback` field in the [Backend](https://gateway.envoyproxy.io/docs/api/extension_types/#backend) API.
+- **Session Persistence in HTTPRoute**: Session persistence is supported in [HTTPRoute](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute) rules for stateful traffic management.
+- **HTTPRouteFilter**: Adds support for Direct Response and Path Regex Rewrites in [HTTPRouteFilter](https://gateway.envoyproxy.io/docs/api/extension_types/#httproutefilter)
+
+### Security Enhancements
+- **JWT Claims-Based Authorization**: Advanced security control with claims-based policies in [SecurityPolicy](https://gateway.envoyproxy.io/docs/api/extension_types/#securitypolicy).
+- **CORS Wildcard Matching**: Wildcard matching for `AllowMethods` and `AllowHeaders` settings.
+- **OIDC Flow Support**: Added nonce support for OIDC authorization.
+
+### Observability & Tracing
+- **Datadog Tracing Integration**: Improved support for Datadog tracing in [EnvoyProxy](https://gateway.envoyproxy.io/docs/api/extension_types/#envoyproxy) CRD.
+- **Listener Access Logs**: Adds support for configuring Listener level Access Logs for EnvoyProxy.
+- **Native Prometheus Metrics**: Introduced a Prometheus metrics endpoint for rate limit monitoring.
+
+### Helm Customization
+- **SecurityContext Options**: Customizable security context for improved deployment.
+- **NodeSelector and PriorityClassName**: Added for more granular deployment configuration.
+
+---
+
+## 🐞 Bug Fixes
+
+- Fixed xDS translation failure when the WASM HTTP code source was configured without an SHA.
+- Resolved unsupported listener protocol types causing errors in Gateway status updates.
+- Fixed `BackendTLSPolicy` causing crashes due to invalid `sectionName` in `Backend` configurations.
+- Fixed propagation delays in `SecurityPolicy` updates for `HTTPRoute` when using `targetSelectors`.
+- Improved `JSONPath` to `JSONPatch` translation accuracy.
+- Fixed unwanted `/` appearing in paths when using prefix rewrites.
+- Corrected nil pointer errors when configuring hash load balancing.
+- Fixed active health check issues where `expectedStatuses` was not functioning properly.
+- Ensured correct status updates for `Backend` resources and `HTTPRoute`.
+
+---
+
+## 🚀 Performance Improvements
+
+- **Memory Optimization**: Enhanced memory usage by eliminating redundant resource storage.
+
+---
+
+## ⚙️ Other Notable Changes
+
+- **Envoy Upgrade**: Now using Envoy [v1.32.1](https://www.envoyproxy.io/docs/envoy/v1.32.1/version_history/v1.32/v1.32.1) for added stability and performance.
+- **Optional Alpha CRD Watching**: Allows Envoy Gateway to run with older Gateway API versions.
+
+
+[Release Notes]: ./notes/v1.2.0
+[matrix]: ./matrix
+[docs]: /v1.2/
+[Install]: /v1.2/install
diff --git a/site/content/en/v0.2/contributions/CODEOWNERS.md b/site/content/en/v0.2/contributions/CODEOWNERS.md
index 63b751abde5..b4c4c737e19 100644
--- a/site/content/en/v0.2/contributions/CODEOWNERS.md
+++ b/site/content/en/v0.2/contributions/CODEOWNERS.md
@@ -5,7 +5,7 @@ description: "This section includes Maintainers of Envoy Gateway."
## The following maintainers, listed in alphabetical order, own everything
-- @AliceProxy
+- @Alice-Lilith
- @arkodg
- @Xunzhuo
- @zirain
diff --git a/site/content/en/v0.2/contributions/RELEASING.md b/site/content/en/v0.2/contributions/RELEASING.md
index bad13a6830c..ad0143bdeb9 100644
--- a/site/content/en/v0.2/contributions/RELEASING.md
+++ b/site/content/en/v0.2/contributions/RELEASING.md
@@ -97,10 +97,10 @@ Configuration looks like following:
cherrypick/release-v0.4
# put release manager here
reviewers: |
- AliceProxy
+ Alice-Lilith
```
-Replace `v0.4` with real branch name, and `AliceProxy` with the real name of RM.
+Replace `v0.4` with real branch name, and `Alice-Lilith` with the real name of RM.
## Minor Release
diff --git a/site/content/en/v0.3/contributions/CODEOWNERS.md b/site/content/en/v0.3/contributions/CODEOWNERS.md
index 63b751abde5..b4c4c737e19 100644
--- a/site/content/en/v0.3/contributions/CODEOWNERS.md
+++ b/site/content/en/v0.3/contributions/CODEOWNERS.md
@@ -5,7 +5,7 @@ description: "This section includes Maintainers of Envoy Gateway."
## The following maintainers, listed in alphabetical order, own everything
-- @AliceProxy
+- @Alice-Lilith
- @arkodg
- @Xunzhuo
- @zirain
diff --git a/site/content/en/v0.3/contributions/RELEASING.md b/site/content/en/v0.3/contributions/RELEASING.md
index bad13a6830c..ad0143bdeb9 100644
--- a/site/content/en/v0.3/contributions/RELEASING.md
+++ b/site/content/en/v0.3/contributions/RELEASING.md
@@ -97,10 +97,10 @@ Configuration looks like following:
cherrypick/release-v0.4
# put release manager here
reviewers: |
- AliceProxy
+ Alice-Lilith
```
-Replace `v0.4` with real branch name, and `AliceProxy` with the real name of RM.
+Replace `v0.4` with real branch name, and `Alice-Lilith` with the real name of RM.
## Minor Release
diff --git a/site/content/en/v0.3/user/authn.md b/site/content/en/v0.3/user/authn.md
index a4887d57438..127269592c4 100644
--- a/site/content/en/v0.3/user/authn.md
+++ b/site/content/en/v0.3/user/authn.md
@@ -57,7 +57,7 @@ A `401` HTTP response code should be returned.
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
__Note:__ The above command decodes and returns the token's payload. You can replace `f2` with `f1` to view the token's
diff --git a/site/content/en/v0.4/contributions/CODEOWNERS.md b/site/content/en/v0.4/contributions/CODEOWNERS.md
index 63b751abde5..b4c4c737e19 100644
--- a/site/content/en/v0.4/contributions/CODEOWNERS.md
+++ b/site/content/en/v0.4/contributions/CODEOWNERS.md
@@ -5,7 +5,7 @@ description: "This section includes Maintainers of Envoy Gateway."
## The following maintainers, listed in alphabetical order, own everything
-- @AliceProxy
+- @Alice-Lilith
- @arkodg
- @Xunzhuo
- @zirain
diff --git a/site/content/en/v0.4/contributions/RELEASING.md b/site/content/en/v0.4/contributions/RELEASING.md
index bad13a6830c..ad0143bdeb9 100644
--- a/site/content/en/v0.4/contributions/RELEASING.md
+++ b/site/content/en/v0.4/contributions/RELEASING.md
@@ -97,10 +97,10 @@ Configuration looks like following:
cherrypick/release-v0.4
# put release manager here
reviewers: |
- AliceProxy
+ Alice-Lilith
```
-Replace `v0.4` with real branch name, and `AliceProxy` with the real name of RM.
+Replace `v0.4` with real branch name, and `Alice-Lilith` with the real name of RM.
## Minor Release
diff --git a/site/content/en/v0.4/user/authn.md b/site/content/en/v0.4/user/authn.md
index 907e16f752e..50cd89e8112 100644
--- a/site/content/en/v0.4/user/authn.md
+++ b/site/content/en/v0.4/user/authn.md
@@ -57,7 +57,7 @@ A `401` HTTP response code should be returned.
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
__Note:__ The above command decodes and returns the token's payload. You can replace `f2` with `f1` to view the token's
diff --git a/site/content/en/v0.5/contributions/CODEOWNERS.md b/site/content/en/v0.5/contributions/CODEOWNERS.md
index 63b751abde5..b4c4c737e19 100644
--- a/site/content/en/v0.5/contributions/CODEOWNERS.md
+++ b/site/content/en/v0.5/contributions/CODEOWNERS.md
@@ -5,7 +5,7 @@ description: "This section includes Maintainers of Envoy Gateway."
## The following maintainers, listed in alphabetical order, own everything
-- @AliceProxy
+- @Alice-Lilith
- @arkodg
- @Xunzhuo
- @zirain
diff --git a/site/content/en/v0.5/contributions/RELEASING.md b/site/content/en/v0.5/contributions/RELEASING.md
index 206c9f0589d..7e02ccff581 100644
--- a/site/content/en/v0.5/contributions/RELEASING.md
+++ b/site/content/en/v0.5/contributions/RELEASING.md
@@ -97,10 +97,10 @@ Configuration looks like following:
cherrypick/release-v0.4
# put release manager here
reviewers: |
- AliceProxy
+ Alice-Lilith
```
-Replace `v0.4` with real branch name, and `AliceProxy` with the real name of RM.
+Replace `v0.4` with real branch name, and `Alice-Lilith` with the real name of RM.
## Minor Release
diff --git a/site/content/en/v0.5/user/authn.md b/site/content/en/v0.5/user/authn.md
index 77954272288..d7f7bc2187a 100644
--- a/site/content/en/v0.5/user/authn.md
+++ b/site/content/en/v0.5/user/authn.md
@@ -57,7 +57,7 @@ A `401` HTTP response code should be returned.
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
__Note:__ The above command decodes and returns the token's payload. You can replace `f2` with `f1` to view the token's
diff --git a/site/content/en/v0.5/user/envoy-patch-policy.md b/site/content/en/v0.5/user/envoy-patch-policy.md
index cf1f1d78abe..453f53d2ef9 100644
--- a/site/content/en/v0.5/user/envoy-patch-policy.md
+++ b/site/content/en/v0.5/user/envoy-patch-policy.md
@@ -10,7 +10,7 @@ is unstable and the outcome may change across versions. Use at your own risk.
## Introduction
The [EnvoyPatchPolicy][] API allows user to modify the output [xDS][]
-configuration generated by Envoy Gateway intended for EnvoyProxy,
+configuration generated by Envoy Gateway intended for EnvoyProxy,
using [JSON Patch][] semantics.
## Motivation
@@ -30,7 +30,7 @@ Before proceeding, you should be able to query the example backend using HTTP.
* By default EnvoyPatchPolicy][] is disabled. Lets enable it in the [EnvoyGateway][] startup configuration
* The default installation of Envoy Gateway installs a default [EnvoyGateway][] configuration and attaches it
-using a `ConfigMap`. In the next step, we will update this resource to enable EnvoyPatchPolicy.
+using a `ConfigMap`. In the next step, we will update this resource to enable EnvoyPatchPolicy.
```shell
@@ -188,7 +188,7 @@ status:
## Caveats
-This API will always be an unstable API and the same outcome cannot be garunteed
+This API will always be an unstable API and the same outcome cannot be guaranteed
across versions for these reasons
* The Envoy Proxy API might deprecate and remove API fields
* Envoy Gateway might alter the xDS translation creating a different xDS output
diff --git a/site/content/en/v0.5/user/rate-limit.md b/site/content/en/v0.5/user/rate-limit.md
index 5f97900c494..1c2dc5c1490 100644
--- a/site/content/en/v0.5/user/rate-limit.md
+++ b/site/content/en/v0.5/user/rate-limit.md
@@ -648,11 +648,11 @@ EOF
Get the JWT used for testing request authentication:
```shell
-TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
```
```shell
-TOKEN1=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/with-different-claim.jwt -s) && echo "$TOKEN1" | cut -d '.' -f2 - | base64 --decode -
+TOKEN1=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/with-different-claim.jwt -s) && echo "$TOKEN1" | cut -d '.' -f2 - | base64 --decode
```
### Rate limit by carrying `TOKEN`
diff --git a/site/content/en/v0.5/user/tls-cert-manager.md b/site/content/en/v0.5/user/tls-cert-manager.md
index 2be531c3ce8..67fbca5742d 100644
--- a/site/content/en/v0.5/user/tls-cert-manager.md
+++ b/site/content/en/v0.5/user/tls-cert-manager.md
@@ -76,7 +76,7 @@ EOF
We now have to patch the example Gateway to reference cert-manager:
```console
-$ kubectl patch gateway/eg --patch-file - < openssl.conf <This will be ignored if sink type is ALS. |
+| `matches` | _string array_ | true | Matches defines the match conditions for accesslog in CEL expression. An accesslog will be emitted only when one or more match conditions are evaluated to true. Invalid [CEL](https://www.envoyproxy.io/docs/envoy/latest/xds/type/v3/cel.proto.html#common-expression-language-cel-proto) expressions will be ignored. |
| `sinks` | _[ProxyAccessLogSink](#proxyaccesslogsink) array_ | true | Sinks defines the sinks of accesslog. |
diff --git a/site/content/en/v1.1/boilerplates/prerequisites.md b/site/content/en/v1.1/boilerplates/prerequisites.md
new file mode 100644
index 00000000000..064238e4d13
--- /dev/null
+++ b/site/content/en/v1.1/boilerplates/prerequisites.md
@@ -0,0 +1,24 @@
+---
+---
+
+Follow the steps from the [Quickstart](../tasks/quickstart) task to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+Verify the Gateway status:
+
+{{< tabpane text=true >}}
+{{% tab header="kubectl" %}}
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+{{% /tab %}}
+{{% tab header="egctl (experimental)" %}}
+
+```shell
+egctl x status gateway -v
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
diff --git a/site/content/en/v1.1/concepts/concepts_overview.md b/site/content/en/v1.1/concepts/concepts_overview.md
index 31838b520f2..9af9a3fff10 100644
--- a/site/content/en/v1.1/concepts/concepts_overview.md
+++ b/site/content/en/v1.1/concepts/concepts_overview.md
@@ -10,13 +10,12 @@ There are several resources that play a part in enabling you to meet your Kubern
There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
-# Overview
-
-## Kubernetes Gateway API Resources
+### Kubernetes Gateway API Resources
- **GatewayClass:** Defines a class of Gateways with common configuration.
- **Gateway:** Specifies how traffic can enter the cluster.
- **Routes:** **HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute:** Define routing rules for different types of traffic.
-## Envoy Gateway (EG) API Resources
+
+### Envoy Gateway (EG) API Resources
- **EnvoyProxy:** Represents the deployment and configuration of the Envoy proxy within a Kubernetes cluster, managing its lifecycle and settings.
- **EnvoyPatchPolicy, ClientTrafficPolicy, SecurityPolicy, BackendTrafficPolicy, EnvoyExtensionPolicy, BackendTLSPolicy:** Additional policies and configurations specific to Envoy Gateway.
- **Backend:** A resource that makes routing to cluster-external backends easier and makes access to external processes via Unix Domain Sockets possible.
diff --git a/site/content/en/v1.1/install/install-yaml.md b/site/content/en/v1.1/install/install-yaml.md
index e675f15fbec..c0a8d1caa72 100644
--- a/site/content/en/v1.1/install/install-yaml.md
+++ b/site/content/en/v1.1/install/install-yaml.md
@@ -13,7 +13,7 @@ installation, it is recommended that you use helm.
Envoy Gateway is designed to run in Kubernetes for production. The most essential requirements are:
-* Kubernetes 1.25 or later
+* Kubernetes 1.27 or later
* The `kubectl` command-line tool
{{% alert title="Compatibility Matrix" color="warning" %}}
@@ -37,3 +37,31 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more.
2. Next Steps
Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks).
+
+## Upgrading from v1.0
+
+Due to breaking changes in Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1.
+
+1. Delete `BackendTLSPolicy` CRD (and resources):
+
+```shell
+kubectl delete crd backendtlspolicies.gateway.networking.k8s.io
+```
+
+2. Update Gateway-API and Envoy Gateway CRDs:
+
+```shell
+helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-crds.yaml
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated
+```
+
+3. Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes)
+
+4. Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef.
+
+5. Install Envoy Gateway {{< yaml-version >}}:
+
+```shell
+helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system
+```
diff --git a/site/content/en/v1.1/tasks/extensibility/envoy-patch-policy.md b/site/content/en/v1.1/tasks/extensibility/envoy-patch-policy.md
index ff819754d1f..318cfab8a31 100644
--- a/site/content/en/v1.1/tasks/extensibility/envoy-patch-policy.md
+++ b/site/content/en/v1.1/tasks/extensibility/envoy-patch-policy.md
@@ -111,7 +111,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -151,7 +150,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -195,7 +193,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -235,7 +232,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -273,8 +269,8 @@ kubectl patch httproute backend --type=json --patch '
* Test it out by specifying a path apart from `/get`
-```
-$ curl --header "Host: www.example.com" http://localhost:8888/find
+```shell
+$ curl --header "Host: www.example.com" http://$GATEWAY_HOST/find
Handling connection for 8888
could not find what you are looking for
```
@@ -322,7 +318,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
status:
conditions:
@@ -345,7 +340,7 @@ status:
## Caveats
-This API will always be an unstable API and the same outcome cannot be garunteed
+This API will always be an unstable API and the same outcome cannot be guaranteed
across versions for these reasons
* The Envoy Proxy API might deprecate and remove API fields
* Envoy Gateway might alter the xDS translation creating a different xDS output
diff --git a/site/content/en/v1.1/tasks/extensibility/ext-proc.md b/site/content/en/v1.1/tasks/extensibility/ext-proc.md
index 9028447ab09..31ad551c63b 100644
--- a/site/content/en/v1.1/tasks/extensibility/ext-proc.md
+++ b/site/content/en/v1.1/tasks/extensibility/ext-proc.md
@@ -113,10 +113,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
@@ -139,10 +139,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
diff --git a/site/content/en/v1.1/tasks/extensibility/extension-server.md b/site/content/en/v1.1/tasks/extensibility/extension-server.md
index 7d67c23f6da..323ce5642ea 100644
--- a/site/content/en/v1.1/tasks/extensibility/extension-server.md
+++ b/site/content/en/v1.1/tasks/extensibility/extension-server.md
@@ -1,5 +1,6 @@
---
title: "Envoy Gateway Extension Server"
+linkTitle: "Extension Server"
---
This task explains how to extend Envoy Gateway using an Extension Server. Envoy Gateway
diff --git a/site/content/en/v1.1/tasks/extensibility/wasm.md b/site/content/en/v1.1/tasks/extensibility/wasm.md
index d973de77950..5d2495cf566 100644
--- a/site/content/en/v1.1/tasks/extensibility/wasm.md
+++ b/site/content/en/v1.1/tasks/extensibility/wasm.md
@@ -23,7 +23,7 @@ kubectl get gateway/eg -o yaml
## Configuration
-Envoy Gateway supports two types of Wasm extensions:
+Envoy Gateway supports two types of Wasm extensions:
* HTTP Wasm Extension: The Wasm extension is fetched from a remote URL.
* Image Wasm Extension: The Wasm extension is packaged as an OCI image and fetched from an image registry.
@@ -44,17 +44,17 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
wasm:
- name: wasm-filter
rootID: my_root_id
code:
type: HTTP
http:
- url: https://raw.githubusercontent.com/envoyproxy/envoy/main/examples/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
+ url: https://raw.githubusercontent.com/envoyproxy/examples/main/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0
EOF
```
@@ -70,17 +70,17 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
wasm:
- name: wasm-filter
rootID: my_root_id
code:
type: HTTP
http:
- url: https://raw.githubusercontent.com/envoyproxy/envoy/main/examples/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
+ url: https://raw.githubusercontent.com/envoyproxy/examples/main/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0
```
@@ -90,7 +90,7 @@ spec:
Verify the EnvoyExtensionPolicy status:
```shell
-kubectl get envoyextensionpolicy/http-wasm-source-test -o yaml
+kubectl get envoyextensionpolicy/wasm-test -o yaml
```
### Image Wasm Extension
@@ -107,8 +107,8 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
@@ -132,17 +132,17 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
- - name: wasm-filter
- rootID: my_root_id
- code:
- type: Image
- image:
- url: zhaohuabing/testwasm:v0.0.1
+ - name: wasm-filter
+ rootID: my_root_id
+ code:
+ type: Image
+ image:
+ url: zhaohuabing/testwasm:v0.0.1
```
{{% /tab %}}
@@ -151,9 +151,148 @@ spec:
Verify the EnvoyExtensionPolicy status:
```shell
-kubectl get envoyextensionpolicy/http-wasm-source-test -o yaml
+kubectl get envoyextensionpolicy/wasm-test -o yaml
+```
+
+### Wasm Extension Configuration
+
+This [EnvoyExtensionPolicy][] configuration fetches the Wasm extension from an OCI image and uses a config block to pass parameters to the extension when it's loaded.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the EnvoyExtensionPolicy status:
+
+```shell
+kubectl get envoyextensionpolicy/wasm-test-o yaml
+```
+
+### Wasm Extension Configuration through Environment variables
+
+It is also possible to configure a wasm extension using environment variables from the host envoy process. Keys for the env vars to be shared are defined in a `hostKeys` block.
+
+This is especially useful for sharing secure data from environment vars on the envoy process set using [valueFrom](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables) a Kubernetes secret.
+
+Note that setting an env var on the envoy process requires a custom [EnvoyProxy](../../api/extension_types#envoyproxy) configuration.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
### Testing
Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
diff --git a/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md b/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md
index 562237bfc43..892c3496ff0 100644
--- a/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md
+++ b/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md
@@ -3,15 +3,68 @@ title: "Customize EnvoyProxy"
---
Envoy Gateway provides an [EnvoyProxy][] CRD that can be linked to the ParametersRef
-in GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
+in a Gateway and GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
Service. To learn more about GatewayClass and ParametersRef, please refer to [Gateway API documentation][].
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
-Before you start, you need to add `ParametersRef` in GatewayClass, and refer to EnvoyProxy Config:
+Before you start, you need to add `Infrastructure.ParametersRef` in Gateway, and refer to EnvoyProxy Config:
+**Note**: `MergeGateways` cannot be set to `true` in your EnvoyProxy config if attaching to the Gateway.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+You can also attach the EnvoyProxy resource to the GatewayClass using the `parametersRef` field.
+This configuration is discouraged if you plan on creating multiple Gateways linking to the same
+GatewayClass and would like different infrastructure configurations for each of them.
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -28,7 +81,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
EOF
```
@@ -48,7 +101,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
```
{{% /tab %}}
@@ -67,7 +120,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -87,7 +140,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -119,7 +172,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -140,7 +193,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -168,7 +221,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -191,7 +244,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -221,7 +274,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -248,7 +301,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -280,7 +333,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -305,7 +358,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -339,7 +392,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -368,7 +421,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -404,7 +457,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -426,7 +479,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -459,7 +512,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
bootstrap:
type: Replace
@@ -547,7 +600,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
bootstrap:
type: Replace
@@ -649,7 +702,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -677,7 +730,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -713,7 +766,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -730,7 +783,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -756,7 +809,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -792,7 +845,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -835,7 +888,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -860,7 +913,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -918,7 +971,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
@@ -938,7 +991,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
diff --git a/site/content/en/v1.1/tasks/quickstart.md b/site/content/en/v1.1/tasks/quickstart.md
index 03d7b6de842..e1943c21e92 100644
--- a/site/content/en/v1.1/tasks/quickstart.md
+++ b/site/content/en/v1.1/tasks/quickstart.md
@@ -12,7 +12,7 @@ A Kubernetes cluster.
__Note:__ Refer to the [Compatibility Matrix](/news/releases/matrix) for supported Kubernetes versions.
-__Note:__ In case your Kubernetes cluster, does not have a LoadBalancer implementation, we recommend installing one
+__Note:__ In case your Kubernetes cluster does not have a LoadBalancer implementation, we recommend installing one
so the `Gateway` resource has an Address associated with it. We recommend using [MetalLB](https://metallb.universe.tf/installation/).
__Note:__ For Mac user, you need install and run [Docker Mac Net Connect](https://github.com/chipmk/docker-mac-net-connect) to make the Docker network work.
@@ -92,34 +92,6 @@ curl --verbose --header "Host: www.example.com" http://localhost:8888/get
{{% /tab %}}
{{< /tabpane >}}
-## v1.1 Upgrade Notes
-
-Due to breaking changes in the Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1.
-
-Delete `BackendTLSPolicy` CRD (and resources):
-
-```shell
-kubectl delete crd backendtlspolicies.gateway.networking.k8s.io
-```
-
-Update Gateway-API and Envoy Gateway CRDs:
-
-```shell
-helm pull oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 --untar
-kubectl apply -f ./gateway-helm/crds/gatewayapi-crds.yaml
-kubectl apply -f ./gateway-helm/crds/generated
-```
-
-Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes)
-
-Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef.
-
-Install Envoy Gateway v1.1.0:
-
-```shell
-helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system
-```
-
## What to explore next?
In this quickstart, you have:
diff --git a/site/content/en/v1.1/tasks/security/backend-tls.md b/site/content/en/v1.1/tasks/security/backend-tls.md
index 53e9ccbd44a..3aadbc34714 100644
--- a/site/content/en/v1.1/tasks/security/backend-tls.md
+++ b/site/content/en/v1.1/tasks/security/backend-tls.md
@@ -25,11 +25,30 @@ Create a root certificate and private key to sign certificates:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout ca.key -out ca.crt
```
-Create a certificate and a private key for `www.example.com`:
+Create a certificate and a private key for `www.example.com`.
+
+First, create an openssl configuration file:
+
+```shell
+cat > openssl.conf < |
+| `http/1.1` | HTTPProtocolVersion1_1 specifies that HTTP/1.1 should be negotiable with ALPN |
+| `h2` | HTTPProtocolVersion2 specifies that HTTP/2 should be negotiable with ALPN |
+
+
+#### ALSEnvoyProxyAccessLog
+
+
+
+ALSEnvoyProxyAccessLog defines the gRPC Access Log Service (ALS) sink.
+The service must implement the Envoy gRPC Access Log Service streaming API:
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/accesslog/v3/als.proto
+Access log format information is passed in the form of gRPC metadata when the
+stream is established. Specifically, the following metadata is passed:
+
+
+- `x-accesslog-text` - The access log format string when a Text format is used.
+- `x-accesslog-attr` - JSON encoded key/value pairs when a JSON format is used.
+
+_Appears in:_
+- [ProxyAccessLogSink](#proxyaccesslogsink)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+| `logName` | _string_ | false | LogName defines the friendly name of the access log to be returned in StreamAccessLogsMessage.Identifier. This allows the access log server to differentiate between different access logs coming from the same Envoy. |
+| `type` | _[ALSEnvoyProxyAccessLogType](#alsenvoyproxyaccesslogtype)_ | true | Type defines the type of accesslog. Supported types are "HTTP" and "TCP". |
+| `http` | _[ALSEnvoyProxyHTTPAccessLogConfig](#alsenvoyproxyhttpaccesslogconfig)_ | false | HTTP defines additional configuration specific to HTTP access logs. |
+
+
+#### ALSEnvoyProxyAccessLogType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+
+| Value | Description |
+| ----- | ----------- |
+| `HTTP` | ALSEnvoyProxyAccessLogTypeHTTP defines the HTTP access log type and will populate StreamAccessLogsMessage.http_logs. |
+| `TCP` | ALSEnvoyProxyAccessLogTypeTCP defines the TCP access log type and will populate StreamAccessLogsMessage.tcp_logs. |
+
+
+#### ALSEnvoyProxyHTTPAccessLogConfig
+
+
+
+
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `requestHeaders` | _string array_ | false | RequestHeaders defines request headers to include in log entries sent to the access log service. |
+| `responseHeaders` | _string array_ | false | ResponseHeaders defines response headers to include in log entries sent to the access log service. |
+| `responseTrailers` | _string array_ | false | ResponseTrailers defines response trailers to include in log entries sent to the access log service. |
+
+
+#### ActiveHealthCheck
+
+
+
+ActiveHealthCheck defines the active health check configuration.
+EG supports various types of active health checking including HTTP, TCP.
+
+_Appears in:_
+- [HealthCheck](#healthcheck)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `timeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | Timeout defines the time to wait for a health check response. |
+| `interval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | Interval defines the time between active health checks. |
+| `unhealthyThreshold` | _integer_ | false | UnhealthyThreshold defines the number of unhealthy health checks required before a backend host is marked unhealthy. |
+| `healthyThreshold` | _integer_ | false | HealthyThreshold defines the number of healthy health checks required before a backend host is marked healthy. |
+| `type` | _[ActiveHealthCheckerType](#activehealthcheckertype)_ | true | Type defines the type of health checker. |
+| `http` | _[HTTPActiveHealthChecker](#httpactivehealthchecker)_ | false | HTTP defines the configuration of http health checker. It's required while the health checker type is HTTP. |
+| `tcp` | _[TCPActiveHealthChecker](#tcpactivehealthchecker)_ | false | TCP defines the configuration of tcp health checker. It's required while the health checker type is TCP. |
+| `grpc` | _[GRPCActiveHealthChecker](#grpcactivehealthchecker)_ | false | GRPC defines the configuration of the GRPC health checker. It's optional, and can only be used if the specified type is GRPC. |
+
+
+#### ActiveHealthCheckPayload
+
+
+
+ActiveHealthCheckPayload defines the encoding of the payload bytes in the payload.
+
+_Appears in:_
+- [HTTPActiveHealthChecker](#httpactivehealthchecker)
+- [TCPActiveHealthChecker](#tcpactivehealthchecker)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[ActiveHealthCheckPayloadType](#activehealthcheckpayloadtype)_ | true | Type defines the type of the payload. |
+| `text` | _string_ | false | Text payload in plain text. |
+| `binary` | _integer array_ | false | Binary payload base64 encoded. |
+
+
+#### ActiveHealthCheckPayloadType
+
+_Underlying type:_ _string_
+
+ActiveHealthCheckPayloadType is the type of the payload.
+
+_Appears in:_
+- [ActiveHealthCheckPayload](#activehealthcheckpayload)
+
+| Value | Description |
+| ----- | ----------- |
+| `Text` | ActiveHealthCheckPayloadTypeText defines the Text type payload. |
+| `Binary` | ActiveHealthCheckPayloadTypeBinary defines the Binary type payload. |
+
+
+#### ActiveHealthCheckerType
+
+_Underlying type:_ _string_
+
+ActiveHealthCheckerType is the type of health checker.
+
+_Appears in:_
+- [ActiveHealthCheck](#activehealthcheck)
+
+| Value | Description |
+| ----- | ----------- |
+| `HTTP` | ActiveHealthCheckerTypeHTTP defines the HTTP type of health checking. |
+| `TCP` | ActiveHealthCheckerTypeTCP defines the TCP type of health checking. |
+| `GRPC` | ActiveHealthCheckerTypeGRPC defines the GRPC type of health checking. |
+
+
+#### AppProtocolType
+
+_Underlying type:_ _string_
+
+AppProtocolType defines various backend applications protocols supported by Envoy Gateway
+
+_Appears in:_
+- [BackendSpec](#backendspec)
+
+| Value | Description |
+| ----- | ----------- |
+| `gateway.envoyproxy.io/h2c` | AppProtocolTypeH2C defines the HTTP/2 application protocol. |
+| `gateway.envoyproxy.io/ws` | AppProtocolTypeWS defines the WebSocket over HTTP protocol. |
+| `gateway.envoyproxy.io/wss` | AppProtocolTypeWSS defines the WebSocket over HTTPS protocol. |
+
+
+#### Authorization
+
+
+
+Authorization defines the authorization configuration.
+
+
+Note: if neither `Rules` nor `DefaultAction` is specified, the default action is to deny all requests.
+
+_Appears in:_
+- [SecurityPolicySpec](#securitypolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `rules` | _[AuthorizationRule](#authorizationrule) array_ | false | Rules defines a list of authorization rules. These rules are evaluated in order, the first matching rule will be applied, and the rest will be skipped.
For example, if there are two rules: the first rule allows the request and the second rule denies it, when a request matches both rules, it will be allowed. |
+| `defaultAction` | _[AuthorizationAction](#authorizationaction)_ | false | DefaultAction defines the default action to be taken if no rules match. If not specified, the default action is Deny. |
+
+
+#### AuthorizationAction
+
+_Underlying type:_ _string_
+
+AuthorizationAction defines the action to be taken if a rule matches.
+
+_Appears in:_
+- [Authorization](#authorization)
+- [AuthorizationRule](#authorizationrule)
+
+| Value | Description |
+| ----- | ----------- |
+| `Allow` | AuthorizationActionAllow is the action to allow the request. |
+| `Deny` | AuthorizationActionDeny is the action to deny the request. |
+
+
+#### AuthorizationRule
+
+
+
+AuthorizationRule defines a single authorization rule.
+
+_Appears in:_
+- [Authorization](#authorization)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | false | Name is a user-friendly name for the rule. If not specified, Envoy Gateway will generate a unique name for the rule. |
+| `action` | _[AuthorizationAction](#authorizationaction)_ | true | Action defines the action to be taken if the rule matches. |
+| `principal` | _[Principal](#principal)_ | true | Principal specifies the client identity of a request. If there are multiple principal types, all principals must match for the rule to match. For example, if there are two principals: one for client IP and one for JWT claim, the rule will match only if both the client IP and the JWT claim match. |
+
+
+#### BackOffPolicy
+
+
+
+
+
+_Appears in:_
+- [PerRetryPolicy](#perretrypolicy)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `baseInterval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | BaseInterval is the base interval between retries. |
+| `maxInterval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set. The default is 10 times the base_interval |
+
+
+#### Backend
+
+
+
+Backend allows the user to configure the endpoints of a backend and
+the behavior of the connection from Envoy Proxy to the backend.
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`Backend`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[BackendSpec](#backendspec)_ | true | Spec defines the desired state of Backend. |
+| `status` | _[BackendStatus](#backendstatus)_ | true | Status defines the current status of Backend. |
+
+
+#### BackendCluster
+
+
+
+BackendCluster contains all the configuration required for configuring access
+to a backend. This can include multiple endpoints, and settings that apply for
+managing the connection to all these endpoints.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OIDCProvider](#oidcprovider)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+
+
+
+
+
+
+#### BackendConnection
+
+
+
+BackendConnection allows users to configure connection-level settings of backend
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit Soft limit on size of the cluster’s connections read and write buffers. BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. If unspecified, an implementation defined default is applied (32768 bytes). For example, 20Mi, 1Gi, 256Ki etc. Note: that when the suffix is not provided, the value is interpreted as bytes. |
+
+
+#### BackendEndpoint
+
+
+
+BackendEndpoint describes a backend endpoint, which can be either a fully-qualified domain name, IP address or unix domain socket
+corresponding to Envoy's Address: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-address
+
+_Appears in:_
+- [BackendSpec](#backendspec)
+- [ExtensionService](#extensionservice)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `fqdn` | _[FQDNEndpoint](#fqdnendpoint)_ | false | FQDN defines a FQDN endpoint |
+| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Supports both IPv4 and IPv6 addresses. |
+| `unix` | _[UnixSocket](#unixsocket)_ | false | Unix defines the unix domain socket endpoint |
+
+
+#### BackendRef
+
+
+
+BackendRef defines how an ObjectReference that is specific to BackendRef.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [BackendCluster](#backendcluster)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OIDCProvider](#oidcprovider)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `group` | _[Group](#group)_ | false | Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. |
+| `kind` | _[Kind](#kind)_ | false | Kind is the Kubernetes resource kind of the referent. For example "Service".
Defaults to "Service" when not specified.
ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services.
Support: Core (Services with a type other than ExternalName)
Support: Implementation-specific (Services with type ExternalName) |
+| `name` | _[ObjectName](#objectname)_ | true | Name is the name of the referent. |
+| `namespace` | _[Namespace](#namespace)_ | false | Namespace is the namespace of the backend. When unspecified, the local namespace is inferred.
Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.
Support: Core |
+| `port` | _[PortNumber](#portnumber)_ | false | Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. |
+| `fallback` | _boolean_ | false | Fallback indicates whether the backend is designated as a fallback. Multiple fallback backends can be configured. It is highly recommended to configure active or passive health checks to ensure that failover can be detected when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again. The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when the health of the active backends falls below 72%. |
+
+
+#### BackendSpec
+
+
+
+BackendSpec describes the desired state of BackendSpec.
+
+_Appears in:_
+- [Backend](#backend)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `endpoints` | _[BackendEndpoint](#backendendpoint) array_ | true | Endpoints defines the endpoints to be used when connecting to the backend. |
+| `appProtocols` | _[AppProtocolType](#appprotocoltype) array_ | false | AppProtocols defines the application protocols to be supported when connecting to the backend. |
+| `fallback` | _boolean_ | false | Fallback indicates whether the backend is designated as a fallback. It is highly recommended to configure active or passive health checks to ensure that failover can be detected when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again. The overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when the health of the active backends falls below 72%. |
+
+
+#### BackendStatus
+
+
+
+BackendStatus defines the state of Backend
+
+_Appears in:_
+- [Backend](#backend)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `conditions` | _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#condition-v1-meta) array_ | false | Conditions describe the current conditions of the Backend. |
+
+
+#### BackendTLSConfig
+
+
+
+BackendTLSConfig describes the BackendTLS configuration for Envoy Proxy.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `clientCertificateRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | false | ClientCertificateRef defines the reference to a Kubernetes Secret that contains the client certificate and private key for Envoy to use when connecting to backend services and external services, such as ExtAuth, ALS, OpenTelemetry, etc. This secret should be located within the same namespace as the Envoy proxy resource that references it. |
+| `minVersion` | _[TLSVersion](#tlsversion)_ | false | Min specifies the minimal TLS protocol version to allow. The default is TLS 1.2 if this is not specified. |
+| `maxVersion` | _[TLSVersion](#tlsversion)_ | false | Max specifies the maximal TLS protocol version to allow The default is TLS 1.3 if this is not specified. |
+| `ciphers` | _string array_ | false | Ciphers specifies the set of cipher suites supported when negotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3. In non-FIPS Envoy Proxy builds the default cipher list is: - [ECDHE-ECDSA-AES128-GCM-SHA256\|ECDHE-ECDSA-CHACHA20-POLY1305] - [ECDHE-RSA-AES128-GCM-SHA256\|ECDHE-RSA-CHACHA20-POLY1305] - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 In builds using BoringSSL FIPS the default cipher list is: - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 |
+| `ecdhCurves` | _string array_ | false | ECDHCurves specifies the set of supported ECDH curves. In non-FIPS Envoy Proxy builds the default curves are: - X25519 - P-256 In builds using BoringSSL FIPS the default curve is: - P-256 |
+| `signatureAlgorithms` | _string array_ | false | SignatureAlgorithms specifies which signature algorithms the listener should support. |
+| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be exposed by the listener. By default h2 and http/1.1 are enabled. Supported values are: - http/1.0 - http/1.1 - h2 |
+
+
+#### BackendTrafficPolicy
+
+
+
+BackendTrafficPolicy allows the user to configure the behavior of the connection
+between the Envoy Proxy listener and the backend service.
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`BackendTrafficPolicy`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[BackendTrafficPolicySpec](#backendtrafficpolicyspec)_ | true | spec defines the desired state of BackendTrafficPolicy. |
+| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | status defines the current status of BackendTrafficPolicy. |
+
+
+#### BackendTrafficPolicySpec
+
+
+
+BackendTrafficPolicySpec defines the desired state of BackendTrafficPolicy.
+
+_Appears in:_
+- [BackendTrafficPolicy](#backendtrafficpolicy)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to. This policy and the TargetRef MUST be in the same namespace for this Policy to have effect
Deprecated: use targetRefs/targetSelectors instead |
+| `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy is being attached to. |
+| `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels |
+| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints. Defaults to `LeastRequest`. |
+| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
+| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. |
+| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection. Disabled by default. |
+| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. |
+| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests. If not set, circuit breakers will be enabled with the default thresholds |
+| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. |
+| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. |
+| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. |
+| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. |
+| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. |
+| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to inject delays and abort requests to mimic failure scenarios such as service failures and overloads |
+| `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using the same HTTP protocol that the incoming request used. Defaults to false, which means that Envoy will use the protocol indicated by the attached BackendRef. |
+| `responseOverride` | _[ResponseOverride](#responseoverride) array_ | false | ResponseOverride defines the configuration to override specific responses with a custom one. If multiple configurations are specified, the first one to match wins. |
+
+
+#### BasicAuth
+
+
+
+BasicAuth defines the configuration for the HTTP Basic Authentication.
+
+_Appears in:_
+- [SecurityPolicySpec](#securitypolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `users` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the username-password pairs in htpasswd format, used to verify user credentials in the "Authorization" header.
This is an Opaque secret. The username-password pairs should be stored in the key ".htpasswd". As the key name indicates, the value needs to be the htpasswd format, for example: "user1:\{SHA\}hashed_user1_password". Right now, only SHA hash algorithm is supported. Reference to https://httpd.apache.org/docs/2.4/programs/htpasswd.html for more details.
Note: The secret must be in the same namespace as the SecurityPolicy. |
+
+
+#### BootstrapType
+
+_Underlying type:_ _string_
+
+BootstrapType defines the types of bootstrap supported by Envoy Gateway.
+
+_Appears in:_
+- [ProxyBootstrap](#proxybootstrap)
+
+| Value | Description |
+| ----- | ----------- |
+| `Merge` | Merge merges the provided bootstrap with the default one. The provided bootstrap can add or override a value within a map, or add a new value to a list. Please note that the provided bootstrap can't override a value within a list. |
+| `Replace` | Replace replaces the default bootstrap with the provided one. |
+| `JSONPatch` | JSONPatch applies the provided JSONPatches to the default bootstrap. |
+
+
+#### CIDR
+
+_Underlying type:_ _string_
+
+CIDR defines a CIDR Address range.
+A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address range such as "2001:0db8:11a3:09d7::/64".
+
+_Appears in:_
+- [Principal](#principal)
+- [XForwardedForSettings](#xforwardedforsettings)
+
+
+
+#### CORS
+
+
+
+CORS defines the configuration for Cross-Origin Resource Sharing (CORS).
+
+_Appears in:_
+- [SecurityPolicySpec](#securitypolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `allowOrigins` | _[Origin](#origin) array_ | false | AllowOrigins defines the origins that are allowed to make requests. It specifies the allowed origins in the Access-Control-Allow-Origin CORS response header. The value "*" allows any origin to make requests. |
+| `allowMethods` | _string array_ | false | AllowMethods defines the methods that are allowed to make requests. It specifies the allowed methods in the Access-Control-Allow-Methods CORS response header.. The value "*" allows any method to be used. |
+| `allowHeaders` | _string array_ | false | AllowHeaders defines the headers that are allowed to be sent with requests. It specifies the allowed headers in the Access-Control-Allow-Headers CORS response header.. The value "*" allows any header to be sent. |
+| `exposeHeaders` | _string array_ | false | ExposeHeaders defines which response headers should be made accessible to scripts running in the browser. It specifies the headers in the Access-Control-Expose-Headers CORS response header.. The value "*" allows any header to be exposed. |
+| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MaxAge defines how long the results of a preflight request can be cached. It specifies the value in the Access-Control-Max-Age CORS response header.. |
+| `allowCredentials` | _boolean_ | false | AllowCredentials indicates whether a request can include user credentials like cookies, authentication headers, or TLS client certificates. It specifies the value in the Access-Control-Allow-Credentials CORS response header. |
+
+
+#### CircuitBreaker
+
+
+
+CircuitBreaker defines the Circuit Breaker configuration.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `maxConnections` | _integer_ | false | The maximum number of connections that Envoy will establish to the referenced backend defined within a xRoute rule. |
+| `maxPendingRequests` | _integer_ | false | The maximum number of pending requests that Envoy will queue to the referenced backend defined within a xRoute rule. |
+| `maxParallelRequests` | _integer_ | false | The maximum number of parallel requests that Envoy will make to the referenced backend defined within a xRoute rule. |
+| `maxParallelRetries` | _integer_ | false | The maximum number of parallel retries that Envoy will make to the referenced backend defined within a xRoute rule. |
+| `maxRequestsPerConnection` | _integer_ | false | The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule. Default: unlimited. |
+
+
+#### ClaimToHeader
+
+
+
+ClaimToHeader defines a configuration to convert JWT claims into HTTP headers
+
+_Appears in:_
+- [JWTProvider](#jwtprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `header` | _string_ | true | Header defines the name of the HTTP request header that the JWT Claim will be saved into. |
+| `claim` | _string_ | true | Claim is the JWT Claim that should be saved into the header : it can be a nested claim of type (eg. "claim.nested.key", "sub"). The nested claim name must use dot "." to separate the JSON name path. |
+
+
+#### ClientConnection
+
+
+
+ClientConnection allows users to configure connection-level settings of client
+
+_Appears in:_
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `connectionLimit` | _[ConnectionLimit](#connectionlimit)_ | false | ConnectionLimit defines limits related to connections |
+| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit provides configuration for the maximum buffer size in bytes for each incoming connection. BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. For example, 20Mi, 1Gi, 256Ki etc. Note that when the suffix is not provided, the value is interpreted as bytes. Default: 32768 bytes. |
+
+
+#### ClientIPDetectionSettings
+
+
+
+ClientIPDetectionSettings provides configuration for determining the original client IP address for requests.
+
+_Appears in:_
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `xForwardedFor` | _[XForwardedForSettings](#xforwardedforsettings)_ | false | XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address. |
+| `customHeader` | _[CustomHeaderExtensionSettings](#customheaderextensionsettings)_ | false | CustomHeader provides configuration for determining the client IP address for a request based on a trusted custom HTTP header. This uses the custom_header original IP detection extension. Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto for more details. |
+
+
+#### ClientTLSSettings
+
+
+
+
+
+_Appears in:_
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `clientValidation` | _[ClientValidationContext](#clientvalidationcontext)_ | false | ClientValidation specifies the configuration to validate the client initiating the TLS connection to the Gateway listener. |
+| `minVersion` | _[TLSVersion](#tlsversion)_ | false | Min specifies the minimal TLS protocol version to allow. The default is TLS 1.2 if this is not specified. |
+| `maxVersion` | _[TLSVersion](#tlsversion)_ | false | Max specifies the maximal TLS protocol version to allow The default is TLS 1.3 if this is not specified. |
+| `ciphers` | _string array_ | false | Ciphers specifies the set of cipher suites supported when negotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3. In non-FIPS Envoy Proxy builds the default cipher list is: - [ECDHE-ECDSA-AES128-GCM-SHA256\|ECDHE-ECDSA-CHACHA20-POLY1305] - [ECDHE-RSA-AES128-GCM-SHA256\|ECDHE-RSA-CHACHA20-POLY1305] - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 In builds using BoringSSL FIPS the default cipher list is: - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 |
+| `ecdhCurves` | _string array_ | false | ECDHCurves specifies the set of supported ECDH curves. In non-FIPS Envoy Proxy builds the default curves are: - X25519 - P-256 In builds using BoringSSL FIPS the default curve is: - P-256 |
+| `signatureAlgorithms` | _string array_ | false | SignatureAlgorithms specifies which signature algorithms the listener should support. |
+| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be exposed by the listener. By default h2 and http/1.1 are enabled. Supported values are: - http/1.0 - http/1.1 - h2 |
+| `session` | _[Session](#session)_ | false | Session defines settings related to TLS session management. |
+
+
+#### ClientTimeout
+
+
+
+
+
+_Appears in:_
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `tcp` | _[TCPClientTimeout](#tcpclienttimeout)_ | false | Timeout settings for TCP. |
+| `http` | _[HTTPClientTimeout](#httpclienttimeout)_ | false | Timeout settings for HTTP. |
+
+
+#### ClientTrafficPolicy
+
+
+
+ClientTrafficPolicy allows the user to configure the behavior of the connection
+between the downstream client and Envoy Proxy listener.
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`ClientTrafficPolicy`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[ClientTrafficPolicySpec](#clienttrafficpolicyspec)_ | true | Spec defines the desired state of ClientTrafficPolicy. |
+| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of ClientTrafficPolicy. |
+
+
+#### ClientTrafficPolicySpec
+
+
+
+ClientTrafficPolicySpec defines the desired state of ClientTrafficPolicy.
+
+_Appears in:_
+- [ClientTrafficPolicy](#clienttrafficpolicy)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to. This policy and the TargetRef MUST be in the same namespace for this Policy to have effect
Deprecated: use targetRefs/targetSelectors instead |
+| `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy is being attached to. |
+| `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels |
+| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the downstream client connection. If defined, sets SO_KEEPALIVE on the listener socket to enable TCP Keepalives. Disabled by default. |
+| `enableProxyProtocol` | _boolean_ | false | EnableProxyProtocol interprets the ProxyProtocol header and adds the Client Address into the X-Forwarded-For header. Note Proxy Protocol must be present when this field is set, else the connection is closed. |
+| `clientIPDetection` | _[ClientIPDetectionSettings](#clientipdetectionsettings)_ | false | ClientIPDetectionSettings provides configuration for determining the original client IP address for requests. |
+| `tls` | _[ClientTLSSettings](#clienttlssettings)_ | false | TLS settings configure TLS termination settings with the downstream client. |
+| `path` | _[PathSettings](#pathsettings)_ | false | Path enables managing how the incoming path set by clients can be normalized. |
+| `headers` | _[HeaderSettings](#headersettings)_ | false | HeaderSettings provides configuration for header management. |
+| `timeout` | _[ClientTimeout](#clienttimeout)_ | false | Timeout settings for the client connections. |
+| `connection` | _[ClientConnection](#clientconnection)_ | false | Connection includes client connection settings. |
+| `http1` | _[HTTP1Settings](#http1settings)_ | false | HTTP1 provides HTTP/1 configuration on the listener. |
+| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration on the listener. |
+| `http3` | _[HTTP3Settings](#http3settings)_ | false | HTTP3 provides HTTP/3 configuration on the listener. |
+| `healthCheck` | _[HealthCheckSettings](#healthchecksettings)_ | false | HealthCheck provides configuration for determining whether the HTTP/HTTPS listener is healthy. |
+
+
+#### ClientValidationContext
+
+
+
+ClientValidationContext holds configuration that can be used to validate the client initiating the TLS connection
+to the Gateway.
+By default, no client specific configuration is validated.
+
+_Appears in:_
+- [ClientTLSSettings](#clienttlssettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `optional` | _boolean_ | false | Optional set to true accepts connections even when a client doesn't present a certificate. Defaults to false, which rejects connections without a valid client certificate. |
+| `caCertificateRefs` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference) array_ | false | CACertificateRefs contains one or more references to Kubernetes objects that contain TLS certificates of the Certificate Authorities that can be used as a trust anchor to validate the certificates presented by the client.
A single reference to a Kubernetes ConfigMap or a Kubernetes Secret, with the CA certificate in a key named `ca.crt` is currently supported.
References to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. |
+
+
+#### ClusterSettings
+
+
+
+ClusterSettings provides the various knobs that can be set to control how traffic to a given
+backend will be configured.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [BackendCluster](#backendcluster)
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OIDCProvider](#oidcprovider)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints. Defaults to `LeastRequest`. |
+| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
+| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. |
+| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection. Disabled by default. |
+| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. |
+| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests. If not set, circuit breakers will be enabled with the default thresholds |
+| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. |
+| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. |
+| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. |
+| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. |
+
+
+#### Compression
+
+
+
+Compression defines the config of enabling compression.
+This can help reduce the bandwidth at the expense of higher CPU.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ProxyPrometheusProvider](#proxyprometheusprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[CompressorType](#compressortype)_ | true | CompressorType defines the compressor type to use for compression. |
+| `gzip` | _[GzipCompressor](#gzipcompressor)_ | false | The configuration for GZIP compressor. |
+
+
+#### CompressorType
+
+_Underlying type:_ _string_
+
+CompressorType defines the types of compressor library supported by Envoy Gateway.
+
+_Appears in:_
+- [Compression](#compression)
+
+
+
+#### ConnectionLimit
+
+
+
+
+
+_Appears in:_
+- [ClientConnection](#clientconnection)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `value` | _integer_ | true | Value of the maximum concurrent connections limit. When the limit is reached, incoming connections will be closed after the CloseDelay duration. |
+| `closeDelay` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | CloseDelay defines the delay to use before closing connections that are rejected once the limit value is reached. Default: none. |
+
+
+#### ConsistentHash
+
+
+
+ConsistentHash defines the configuration related to the consistent hash
+load balancer policy.
+
+_Appears in:_
+- [LoadBalancer](#loadbalancer)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[ConsistentHashType](#consistenthashtype)_ | true | ConsistentHashType defines the type of input to hash on. Valid Type values are "SourceIP", "Header", "Cookie". |
+| `header` | _[Header](#header)_ | false | Header configures the header hash policy when the consistent hash type is set to Header. |
+| `cookie` | _[Cookie](#cookie)_ | false | Cookie configures the cookie hash policy when the consistent hash type is set to Cookie. |
+| `tableSize` | _integer_ | false | The table size for consistent hashing, must be prime number limited to 5000011. |
+
+
+#### ConsistentHashType
+
+_Underlying type:_ _string_
+
+ConsistentHashType defines the type of input to hash on.
+
+_Appears in:_
+- [ConsistentHash](#consistenthash)
+
+| Value | Description |
+| ----- | ----------- |
+| `SourceIP` | SourceIPConsistentHashType hashes based on the source IP address. |
+| `Header` | HeaderConsistentHashType hashes based on a request header. |
+| `Cookie` | CookieConsistentHashType hashes based on a cookie. |
+
+
+#### Cookie
+
+
+
+Cookie defines the cookie hashing configuration for consistent hash based
+load balancing.
+
+_Appears in:_
+- [ConsistentHash](#consistenthash)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | true | Name of the cookie to hash. If this cookie does not exist in the request, Envoy will generate a cookie and set the TTL on the response back to the client based on Layer 4 attributes of the backend endpoint, to ensure that these future requests go to the same backend endpoint. Make sure to set the TTL field for this case. |
+| `ttl` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | TTL of the generated cookie if the cookie is not present. This value sets the Max-Age attribute value. |
+| `attributes` | _object (keys:string, values:string)_ | false | Additional Attributes to set for the generated cookie. |
+
+
+#### CustomHeaderExtensionSettings
+
+
+
+CustomHeaderExtensionSettings provides configuration for determining the client IP address for a request based on
+a trusted custom HTTP header. This uses the the custom_header original IP detection extension.
+Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto
+for more details.
+
+_Appears in:_
+- [ClientIPDetectionSettings](#clientipdetectionsettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | true | Name of the header containing the original downstream remote address, if present. |
+| `failClosed` | _boolean_ | false | FailClosed is a switch used to control the flow of traffic when client IP detection fails. If set to true, the listener will respond with 403 Forbidden when the client IP address cannot be determined. |
+
+
+#### CustomResponse
+
+
+
+CustomResponse defines the configuration for returning a custom response.
+
+_Appears in:_
+- [ResponseOverride](#responseoverride)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `contentType` | _string_ | false | Content Type of the response. This will be set in the Content-Type header. |
+| `body` | _[CustomResponseBody](#customresponsebody)_ | true | Body of the Custom Response |
+
+
+#### CustomResponseBody
+
+
+
+CustomResponseBody
+
+_Appears in:_
+- [CustomResponse](#customresponse)
+- [HTTPDirectResponseFilter](#httpdirectresponsefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[ResponseValueType](#responsevaluetype)_ | true | Type is the type of method to use to read the body value. Valid values are Inline and ValueRef, default is Inline. |
+| `inline` | _string_ | false | Inline contains the value as an inline string. |
+| `valueRef` | _[LocalObjectReference](#localobjectreference)_ | false | ValueRef contains the contents of the body specified as a local object reference. Only a reference to ConfigMap is supported.
The value of key `response.body` in the ConfigMap will be used as the response body. If the key is not found, the first value in the ConfigMap will be used. |
+
+
+#### CustomResponseMatch
+
+
+
+CustomResponseMatch defines the configuration for matching a user response to return a custom one.
+
+_Appears in:_
+- [ResponseOverride](#responseoverride)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `statusCodes` | _[StatusCodeMatch](#statuscodematch) array_ | true | Status code to match on. The match evaluates to true if any of the matches are successful. |
+
+
+#### CustomTag
+
+
+
+
+
+_Appears in:_
+- [ProxyTracing](#proxytracing)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[CustomTagType](#customtagtype)_ | true | Type defines the type of custom tag. |
+| `literal` | _[LiteralCustomTag](#literalcustomtag)_ | true | Literal adds hard-coded value to each span. It's required when the type is "Literal". |
+| `environment` | _[EnvironmentCustomTag](#environmentcustomtag)_ | true | Environment adds value from environment variable to each span. It's required when the type is "Environment". |
+| `requestHeader` | _[RequestHeaderCustomTag](#requestheadercustomtag)_ | true | RequestHeader adds value from request header to each span. It's required when the type is "RequestHeader". |
+
+
+#### CustomTagType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [CustomTag](#customtag)
+
+| Value | Description |
+| ----- | ----------- |
+| `Literal` | CustomTagTypeLiteral adds hard-coded value to each span. |
+| `Environment` | CustomTagTypeEnvironment adds value from environment variable to each span. |
+| `RequestHeader` | CustomTagTypeRequestHeader adds value from request header to each span. |
+
+
+#### DNS
+
+
+
+
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `dnsRefreshRate` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | DNSRefreshRate specifies the rate at which DNS records should be refreshed. Defaults to 30 seconds. |
+| `respectDnsTtl` | _boolean_ | true | RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. Defaults to true. |
+
+
+#### EnvironmentCustomTag
+
+
+
+EnvironmentCustomTag adds value from environment variable to each span.
+
+_Appears in:_
+- [CustomTag](#customtag)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | true | Name defines the name of the environment variable which to extract the value from. |
+| `defaultValue` | _string_ | false | DefaultValue defines the default value to use if the environment variable is not set. |
+
+
+#### EnvoyExtensionPolicy
+
+
+
+EnvoyExtensionPolicy allows the user to configure various envoy extensibility options for the Gateway.
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`EnvoyExtensionPolicy`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[EnvoyExtensionPolicySpec](#envoyextensionpolicyspec)_ | true | Spec defines the desired state of EnvoyExtensionPolicy. |
+| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of EnvoyExtensionPolicy. |
+
+
+#### EnvoyExtensionPolicySpec
+
+
+
+EnvoyExtensionPolicySpec defines the desired state of EnvoyExtensionPolicy.
+
+_Appears in:_
+- [EnvoyExtensionPolicy](#envoyextensionpolicy)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to. This policy and the TargetRef MUST be in the same namespace for this Policy to have effect
Deprecated: use targetRefs/targetSelectors instead |
+| `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy is being attached to. |
+| `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels |
+| `wasm` | _[Wasm](#wasm) array_ | false | Wasm is a list of Wasm extensions to be loaded by the Gateway. Order matters, as the extensions will be loaded in the order they are defined in this list. |
+| `extProc` | _[ExtProc](#extproc) array_ | false | ExtProc is an ordered list of external processing filters that should added to the envoy filter chain |
+
+
+#### EnvoyFilter
+
+_Underlying type:_ _string_
+
+EnvoyFilter defines the type of Envoy HTTP filter.
+
+_Appears in:_
+- [FilterPosition](#filterposition)
+
+| Value | Description |
+| ----- | ----------- |
+| `envoy.filters.http.health_check` | EnvoyFilterHealthCheck defines the Envoy HTTP health check filter. |
+| `envoy.filters.http.fault` | EnvoyFilterFault defines the Envoy HTTP fault filter. |
+| `envoy.filters.http.cors` | EnvoyFilterCORS defines the Envoy HTTP CORS filter. |
+| `envoy.filters.http.ext_authz` | EnvoyFilterExtAuthz defines the Envoy HTTP external authorization filter. |
+| `envoy.filters.http.basic_auth` | EnvoyFilterBasicAuth defines the Envoy HTTP basic authentication filter. |
+| `envoy.filters.http.oauth2` | EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter. |
+| `envoy.filters.http.jwt_authn` | EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter. |
+| `envoy.filters.http.stateful_session` | EnvoyFilterSessionPersistence defines the Envoy HTTP session persistence filter. |
+| `envoy.filters.http.ext_proc` | EnvoyFilterExtProc defines the Envoy HTTP external process filter. |
+| `envoy.filters.http.wasm` | EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter. |
+| `envoy.filters.http.rbac` | EnvoyFilterRBAC defines the Envoy RBAC filter. |
+| `envoy.filters.http.local_ratelimit` | EnvoyFilterLocalRateLimit defines the Envoy HTTP local rate limit filter. |
+| `envoy.filters.http.ratelimit` | EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter. |
+| `envoy.filters.http.custom_response` | EnvoyFilterCustomResponse defines the Envoy HTTP custom response filter. |
+| `envoy.filters.http.router` | EnvoyFilterRouter defines the Envoy HTTP router filter. |
+
+
+#### EnvoyGateway
+
+
+
+EnvoyGateway is the schema for the envoygateways API.
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`EnvoyGateway`
+| `gateway` | _[Gateway](#gateway)_ | false | Gateway defines desired Gateway API specific configuration. If unset, default configuration parameters will apply. |
+| `provider` | _[EnvoyGatewayProvider](#envoygatewayprovider)_ | false | Provider defines the desired provider and provider-specific configuration. If unspecified, the Kubernetes provider is used with default configuration parameters. |
+| `logging` | _[EnvoyGatewayLogging](#envoygatewaylogging)_ | false | Logging defines logging parameters for Envoy Gateway. |
+| `admin` | _[EnvoyGatewayAdmin](#envoygatewayadmin)_ | false | Admin defines the desired admin related abilities. If unspecified, the Admin is used with default configuration parameters. |
+| `telemetry` | _[EnvoyGatewayTelemetry](#envoygatewaytelemetry)_ | false | Telemetry defines the desired control plane telemetry related abilities. If unspecified, the telemetry is used with default configuration. |
+| `rateLimit` | _[RateLimit](#ratelimit)_ | false | RateLimit defines the configuration associated with the Rate Limit service deployed by Envoy Gateway required to implement the Global Rate limiting functionality. The specific rate limit service used here is the reference implementation in Envoy. For more details visit https://github.com/envoyproxy/ratelimit. This configuration is unneeded for "Local" rate limiting. |
+| `extensionManager` | _[ExtensionManager](#extensionmanager)_ | false | ExtensionManager defines an extension manager to register for the Envoy Gateway Control Plane. |
+| `extensionApis` | _[ExtensionAPISettings](#extensionapisettings)_ | false | ExtensionAPIs defines the settings related to specific Gateway API Extensions implemented by Envoy Gateway |
+
+
+#### EnvoyGatewayAdmin
+
+
+
+EnvoyGatewayAdmin defines the Envoy Gateway Admin configuration.
+
+_Appears in:_
+- [EnvoyGateway](#envoygateway)
+- [EnvoyGatewaySpec](#envoygatewayspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `address` | _[EnvoyGatewayAdminAddress](#envoygatewayadminaddress)_ | false | Address defines the address of Envoy Gateway Admin Server. |
+| `enableDumpConfig` | _boolean_ | false | EnableDumpConfig defines if enable dump config in Envoy Gateway logs. |
+| `enablePprof` | _boolean_ | false | EnablePprof defines if enable pprof in Envoy Gateway Admin Server. |
+
+
+#### EnvoyGatewayAdminAddress
+
+
+
+EnvoyGatewayAdminAddress defines the Envoy Gateway Admin Address configuration.
+
+_Appears in:_
+- [EnvoyGatewayAdmin](#envoygatewayadmin)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `port` | _integer_ | false | Port defines the port the admin server is exposed on. |
+| `host` | _string_ | false | Host defines the admin server hostname. |
+
+
+#### EnvoyGatewayCustomProvider
+
+
+
+EnvoyGatewayCustomProvider defines configuration for the Custom provider.
+
+_Appears in:_
+- [EnvoyGatewayProvider](#envoygatewayprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `resource` | _[EnvoyGatewayResourceProvider](#envoygatewayresourceprovider)_ | true | Resource defines the desired resource provider. This provider is used to specify the provider to be used to retrieve the resource configurations such as Gateway API resources |
+| `infrastructure` | _[EnvoyGatewayInfrastructureProvider](#envoygatewayinfrastructureprovider)_ | false | Infrastructure defines the desired infrastructure provider. This provider is used to specify the provider to be used to provide an environment to deploy the out resources like the Envoy Proxy data plane.
Infrastructure is optional, if provider is not specified, No infrastructure provider is available. |
+
+
+#### EnvoyGatewayFileResourceProvider
+
+
+
+EnvoyGatewayFileResourceProvider defines configuration for the File Resource provider.
+
+_Appears in:_
+- [EnvoyGatewayResourceProvider](#envoygatewayresourceprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `paths` | _string array_ | true | Paths are the paths to a directory or file containing the resource configuration. Recursive subdirectories are not currently supported. |
+
+
+#### EnvoyGatewayHostInfrastructureProvider
+
+
+
+EnvoyGatewayHostInfrastructureProvider defines configuration for the Host Infrastructure provider.
+
+_Appears in:_
+- [EnvoyGatewayInfrastructureProvider](#envoygatewayinfrastructureprovider)
+
+
+
+#### EnvoyGatewayInfrastructureProvider
+
+
+
+EnvoyGatewayInfrastructureProvider defines configuration for the Custom Infrastructure provider.
+
+_Appears in:_
+- [EnvoyGatewayCustomProvider](#envoygatewaycustomprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[InfrastructureProviderType](#infrastructureprovidertype)_ | true | Type is the type of infrastructure providers to use. Supported types are "Host". |
+| `host` | _[EnvoyGatewayHostInfrastructureProvider](#envoygatewayhostinfrastructureprovider)_ | false | Host defines the configuration of the Host provider. Host provides runtime deployment of the data plane as a child process on the host environment. |
+
+
+#### EnvoyGatewayKubernetesProvider
+
+
+
+EnvoyGatewayKubernetesProvider defines configuration for the Kubernetes provider.
+
+_Appears in:_
+- [EnvoyGatewayProvider](#envoygatewayprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `rateLimitDeployment` | _[KubernetesDeploymentSpec](#kubernetesdeploymentspec)_ | false | RateLimitDeployment defines the desired state of the Envoy ratelimit deployment resource. If unspecified, default settings for the managed Envoy ratelimit deployment resource are applied. |
+| `watch` | _[KubernetesWatchMode](#kuberneteswatchmode)_ | false | Watch holds configuration of which input resources should be watched and reconciled. |
+| `deploy` | _[KubernetesDeployMode](#kubernetesdeploymode)_ | false | Deploy holds configuration of how output managed resources such as the Envoy Proxy data plane should be deployed |
+| `overwriteControlPlaneCerts` | _boolean_ | false | OverwriteControlPlaneCerts updates the secrets containing the control plane certs, when set. |
+| `leaderElection` | _[LeaderElection](#leaderelection)_ | false | LeaderElection specifies the configuration for leader election. If it's not set up, leader election will be active by default, using Kubernetes' standard settings. |
+| `shutdownManager` | _[ShutdownManager](#shutdownmanager)_ | false | ShutdownManager defines the configuration for the shutdown manager. |
+
+
+#### EnvoyGatewayLogComponent
+
+_Underlying type:_ _string_
+
+EnvoyGatewayLogComponent defines a component that supports a configured logging level.
+
+_Appears in:_
+- [EnvoyGatewayLogging](#envoygatewaylogging)
+
+| Value | Description |
+| ----- | ----------- |
+| `default` | LogComponentGatewayDefault defines the "default"-wide logging component. When specified, all other logging components are ignored. |
+| `provider` | LogComponentProviderRunner defines the "provider" runner component. |
+| `gateway-api` | LogComponentGatewayAPIRunner defines the "gateway-api" runner component. |
+| `xds-translator` | LogComponentXdsTranslatorRunner defines the "xds-translator" runner component. |
+| `xds-server` | LogComponentXdsServerRunner defines the "xds-server" runner component. |
+| `infrastructure` | LogComponentInfrastructureRunner defines the "infrastructure" runner component. |
+| `global-ratelimit` | LogComponentGlobalRateLimitRunner defines the "global-ratelimit" runner component. |
+
+
+#### EnvoyGatewayLogging
+
+
+
+EnvoyGatewayLogging defines logging for Envoy Gateway.
+
+_Appears in:_
+- [EnvoyGateway](#envoygateway)
+- [EnvoyGatewaySpec](#envoygatewayspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `level` | _object (keys:[EnvoyGatewayLogComponent](#envoygatewaylogcomponent), values:[LogLevel](#loglevel))_ | true | Level is the logging level. If unspecified, defaults to "info". EnvoyGatewayLogComponent options: default/provider/gateway-api/xds-translator/xds-server/infrastructure/global-ratelimit. LogLevel options: debug/info/error/warn. |
+
+
+#### EnvoyGatewayMetricSink
+
+
+
+EnvoyGatewayMetricSink defines control plane
+metric sinks where metrics are sent to.
+
+_Appears in:_
+- [EnvoyGatewayMetrics](#envoygatewaymetrics)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[MetricSinkType](#metricsinktype)_ | true | Type defines the metric sink type. EG control plane currently supports OpenTelemetry. |
+| `openTelemetry` | _[EnvoyGatewayOpenTelemetrySink](#envoygatewayopentelemetrysink)_ | true | OpenTelemetry defines the configuration for OpenTelemetry sink. It's required if the sink type is OpenTelemetry. |
+
+
+#### EnvoyGatewayMetrics
+
+
+
+EnvoyGatewayMetrics defines control plane push/pull metrics configurations.
+
+_Appears in:_
+- [EnvoyGatewayTelemetry](#envoygatewaytelemetry)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `sinks` | _[EnvoyGatewayMetricSink](#envoygatewaymetricsink) array_ | true | Sinks defines the metric sinks where metrics are sent to. |
+| `prometheus` | _[EnvoyGatewayPrometheusProvider](#envoygatewayprometheusprovider)_ | true | Prometheus defines the configuration for prometheus endpoint. |
+
+
+#### EnvoyGatewayOpenTelemetrySink
+
+
+
+
+
+_Appears in:_
+- [EnvoyGatewayMetricSink](#envoygatewaymetricsink)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `host` | _string_ | true | Host define the sink service hostname. |
+| `protocol` | _string_ | true | Protocol define the sink service protocol. |
+| `port` | _integer_ | false | Port defines the port the sink service is exposed on. |
+| `exportInterval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | true | ExportInterval configures the intervening time between exports for a Sink. This option overrides any value set for the OTEL_METRIC_EXPORT_INTERVAL environment variable. If ExportInterval is less than or equal to zero, 60 seconds is used as the default. |
+| `exportTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | true | ExportTimeout configures the time a Sink waits for an export to complete before canceling it. This option overrides any value set for the OTEL_METRIC_EXPORT_TIMEOUT environment variable. If ExportTimeout is less than or equal to zero, 30 seconds is used as the default. |
+
+
+#### EnvoyGatewayPrometheusProvider
+
+
+
+EnvoyGatewayPrometheusProvider will expose prometheus endpoint in pull mode.
+
+_Appears in:_
+- [EnvoyGatewayMetrics](#envoygatewaymetrics)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `disable` | _boolean_ | true | Disable defines if disables the prometheus metrics in pull mode. |
+
+
+#### EnvoyGatewayProvider
+
+
+
+EnvoyGatewayProvider defines the desired configuration of a provider.
+
+_Appears in:_
+- [EnvoyGateway](#envoygateway)
+- [EnvoyGatewaySpec](#envoygatewayspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[ProviderType](#providertype)_ | true | Type is the type of provider to use. Supported types are "Kubernetes", "Custom". |
+| `kubernetes` | _[EnvoyGatewayKubernetesProvider](#envoygatewaykubernetesprovider)_ | false | Kubernetes defines the configuration of the Kubernetes provider. Kubernetes provides runtime configuration via the Kubernetes API. |
+| `custom` | _[EnvoyGatewayCustomProvider](#envoygatewaycustomprovider)_ | false | Custom defines the configuration for the Custom provider. This provider allows you to define a specific resource provider and an infrastructure provider. |
+
+
+#### EnvoyGatewayResourceProvider
+
+
+
+EnvoyGatewayResourceProvider defines configuration for the Custom Resource provider.
+
+_Appears in:_
+- [EnvoyGatewayCustomProvider](#envoygatewaycustomprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[ResourceProviderType](#resourceprovidertype)_ | true | Type is the type of resource provider to use. Supported types are "File". |
+| `file` | _[EnvoyGatewayFileResourceProvider](#envoygatewayfileresourceprovider)_ | false | File defines the configuration of the File provider. File provides runtime configuration defined by one or more files. |
+
+
+#### EnvoyGatewaySpec
+
+
+
+EnvoyGatewaySpec defines the desired state of Envoy Gateway.
+
+_Appears in:_
+- [EnvoyGateway](#envoygateway)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `gateway` | _[Gateway](#gateway)_ | false | Gateway defines desired Gateway API specific configuration. If unset, default configuration parameters will apply. |
+| `provider` | _[EnvoyGatewayProvider](#envoygatewayprovider)_ | false | Provider defines the desired provider and provider-specific configuration. If unspecified, the Kubernetes provider is used with default configuration parameters. |
+| `logging` | _[EnvoyGatewayLogging](#envoygatewaylogging)_ | false | Logging defines logging parameters for Envoy Gateway. |
+| `admin` | _[EnvoyGatewayAdmin](#envoygatewayadmin)_ | false | Admin defines the desired admin related abilities. If unspecified, the Admin is used with default configuration parameters. |
+| `telemetry` | _[EnvoyGatewayTelemetry](#envoygatewaytelemetry)_ | false | Telemetry defines the desired control plane telemetry related abilities. If unspecified, the telemetry is used with default configuration. |
+| `rateLimit` | _[RateLimit](#ratelimit)_ | false | RateLimit defines the configuration associated with the Rate Limit service deployed by Envoy Gateway required to implement the Global Rate limiting functionality. The specific rate limit service used here is the reference implementation in Envoy. For more details visit https://github.com/envoyproxy/ratelimit. This configuration is unneeded for "Local" rate limiting. |
+| `extensionManager` | _[ExtensionManager](#extensionmanager)_ | false | ExtensionManager defines an extension manager to register for the Envoy Gateway Control Plane. |
+| `extensionApis` | _[ExtensionAPISettings](#extensionapisettings)_ | false | ExtensionAPIs defines the settings related to specific Gateway API Extensions implemented by Envoy Gateway |
+
+
+#### EnvoyGatewayTelemetry
+
+
+
+EnvoyGatewayTelemetry defines telemetry configurations for envoy gateway control plane.
+Control plane will focus on metrics observability telemetry and tracing telemetry later.
+
+_Appears in:_
+- [EnvoyGateway](#envoygateway)
+- [EnvoyGatewaySpec](#envoygatewayspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `metrics` | _[EnvoyGatewayMetrics](#envoygatewaymetrics)_ | true | Metrics defines metrics configuration for envoy gateway. |
+
+
+#### EnvoyJSONPatchConfig
+
+
+
+EnvoyJSONPatchConfig defines the configuration for patching a Envoy xDS Resource
+using JSONPatch semantic
+
+_Appears in:_
+- [EnvoyPatchPolicySpec](#envoypatchpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[EnvoyResourceType](#envoyresourcetype)_ | true | Type is the typed URL of the Envoy xDS Resource |
+| `name` | _string_ | true | Name is the name of the resource |
+| `operation` | _[JSONPatchOperation](#jsonpatchoperation)_ | true | Patch defines the JSON Patch Operation |
+
+
+#### EnvoyPatchPolicy
+
+
+
+EnvoyPatchPolicy allows the user to modify the generated Envoy xDS
+resources by Envoy Gateway using this patch API
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`EnvoyPatchPolicy`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[EnvoyPatchPolicySpec](#envoypatchpolicyspec)_ | true | Spec defines the desired state of EnvoyPatchPolicy. |
+| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of EnvoyPatchPolicy. |
+
+
+#### EnvoyPatchPolicySpec
+
+
+
+EnvoyPatchPolicySpec defines the desired state of EnvoyPatchPolicy.
+
+_Appears in:_
+- [EnvoyPatchPolicy](#envoypatchpolicy)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[EnvoyPatchType](#envoypatchtype)_ | true | Type decides the type of patch. Valid EnvoyPatchType values are "JSONPatch". |
+| `jsonPatches` | _[EnvoyJSONPatchConfig](#envoyjsonpatchconfig) array_ | false | JSONPatch defines the JSONPatch configuration. |
+| `targetRef` | _[LocalPolicyTargetReference](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReference)_ | true | TargetRef is the name of the Gateway API resource this policy is being attached to. By default, attaching to Gateway is supported and when mergeGateways is enabled it should attach to GatewayClass. This Policy and the TargetRef MUST be in the same namespace for this Policy to have effect and be applied to the Gateway TargetRef |
+| `priority` | _integer_ | true | Priority of the EnvoyPatchPolicy. If multiple EnvoyPatchPolicies are applied to the same TargetRef, they will be applied in the ascending order of the priority i.e. int32.min has the highest priority and int32.max has the lowest priority. Defaults to 0. |
+
+
+#### EnvoyPatchType
+
+_Underlying type:_ _string_
+
+EnvoyPatchType specifies the types of Envoy patching mechanisms.
+
+_Appears in:_
+- [EnvoyPatchPolicySpec](#envoypatchpolicyspec)
+
+| Value | Description |
+| ----- | ----------- |
+| `JSONPatch` | JSONPatchEnvoyPatchType allows the user to patch the generated xDS resources using JSONPatch semantics. For more details on the semantics, please refer to https://datatracker.ietf.org/doc/html/rfc6902 |
+
+
+#### EnvoyProxy
+
+
+
+EnvoyProxy is the schema for the envoyproxies API.
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`EnvoyProxy`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[EnvoyProxySpec](#envoyproxyspec)_ | true | EnvoyProxySpec defines the desired state of EnvoyProxy. |
+| `status` | _[EnvoyProxyStatus](#envoyproxystatus)_ | true | EnvoyProxyStatus defines the actual state of EnvoyProxy. |
+
+
+#### EnvoyProxyKubernetesProvider
+
+
+
+EnvoyProxyKubernetesProvider defines configuration for the Kubernetes resource
+provider.
+
+_Appears in:_
+- [EnvoyProxyProvider](#envoyproxyprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `envoyDeployment` | _[KubernetesDeploymentSpec](#kubernetesdeploymentspec)_ | false | EnvoyDeployment defines the desired state of the Envoy deployment resource. If unspecified, default settings for the managed Envoy deployment resource are applied. |
+| `envoyDaemonSet` | _[KubernetesDaemonSetSpec](#kubernetesdaemonsetspec)_ | false | EnvoyDaemonSet defines the desired state of the Envoy daemonset resource. Disabled by default, a deployment resource is used instead to provision the Envoy Proxy fleet |
+| `envoyService` | _[KubernetesServiceSpec](#kubernetesservicespec)_ | false | EnvoyService defines the desired state of the Envoy service resource. If unspecified, default settings for the managed Envoy service resource are applied. |
+| `envoyHpa` | _[KubernetesHorizontalPodAutoscalerSpec](#kuberneteshorizontalpodautoscalerspec)_ | false | EnvoyHpa defines the Horizontal Pod Autoscaler settings for Envoy Proxy Deployment. Once the HPA is being set, Replicas field from EnvoyDeployment will be ignored. |
+| `useListenerPortAsContainerPort` | _boolean_ | false | UseListenerPortAsContainerPort disables the port shifting feature in the Envoy Proxy. When set to false (default value), if the service port is a privileged port (1-1023), add a constant to the value converting it into an ephemeral port. This allows the container to bind to the port without needing a CAP_NET_BIND_SERVICE capability. |
+| `envoyPDB` | _[KubernetesPodDisruptionBudgetSpec](#kubernetespoddisruptionbudgetspec)_ | false | EnvoyPDB allows to control the pod disruption budget of an Envoy Proxy. |
+
+
+#### EnvoyProxyProvider
+
+
+
+EnvoyProxyProvider defines the desired state of a resource provider.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[ProviderType](#providertype)_ | true | Type is the type of resource provider to use. A resource provider provides infrastructure resources for running the data plane, e.g. Envoy proxy, and optional auxiliary control planes. Supported types are "Kubernetes". |
+| `kubernetes` | _[EnvoyProxyKubernetesProvider](#envoyproxykubernetesprovider)_ | false | Kubernetes defines the desired state of the Kubernetes resource provider. Kubernetes provides infrastructure resources for running the data plane, e.g. Envoy proxy. If unspecified and type is "Kubernetes", default settings for managed Kubernetes resources are applied. |
+
+
+#### EnvoyProxySpec
+
+
+
+EnvoyProxySpec defines the desired state of EnvoyProxy.
+
+_Appears in:_
+- [EnvoyProxy](#envoyproxy)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `provider` | _[EnvoyProxyProvider](#envoyproxyprovider)_ | false | Provider defines the desired resource provider and provider-specific configuration. If unspecified, the "Kubernetes" resource provider is used with default configuration parameters. |
+| `logging` | _[ProxyLogging](#proxylogging)_ | true | Logging defines logging parameters for managed proxies. |
+| `telemetry` | _[ProxyTelemetry](#proxytelemetry)_ | false | Telemetry defines telemetry parameters for managed proxies. |
+| `bootstrap` | _[ProxyBootstrap](#proxybootstrap)_ | false | Bootstrap defines the Envoy Bootstrap as a YAML string. Visit https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-msg-config-bootstrap-v3-bootstrap to learn more about the syntax. If set, this is the Bootstrap configuration used for the managed Envoy Proxy fleet instead of the default Bootstrap configuration set by Envoy Gateway. Some fields within the Bootstrap that are required to communicate with the xDS Server (Envoy Gateway) and receive xDS resources from it are not configurable and will result in the `EnvoyProxy` resource being rejected. Backward compatibility across minor versions is not guaranteed. We strongly recommend using `egctl x translate` to generate a `EnvoyProxy` resource with the `Bootstrap` field set to the default Bootstrap configuration used. You can edit this configuration, and rerun `egctl x translate` to ensure there are no validation errors. |
+| `concurrency` | _integer_ | false | Concurrency defines the number of worker threads to run. If unset, it defaults to the number of cpuset threads on the platform. |
+| `routingType` | _[RoutingType](#routingtype)_ | false | RoutingType can be set to "Service" to use the Service Cluster IP for routing to the backend, or it can be set to "Endpoint" to use Endpoint routing. The default is "Endpoint". |
+| `extraArgs` | _string array_ | false | ExtraArgs defines additional command line options that are provided to Envoy. More info: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#command-line-options Note: some command line options are used internally(e.g. --log-level) so they cannot be provided here. |
+| `mergeGateways` | _boolean_ | false | MergeGateways defines if Gateway resources should be merged onto the same Envoy Proxy Infrastructure. Setting this field to true would merge all Gateway Listeners under the parent Gateway Class. This means that the port, protocol and hostname tuple must be unique for every listener. If a duplicate listener is detected, the newer listener (based on timestamp) will be rejected and its status will be updated with a "Accepted=False" condition. |
+| `shutdown` | _[ShutdownConfig](#shutdownconfig)_ | false | Shutdown defines configuration for graceful envoy shutdown process. |
+| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. The FilterPosition in the list will be applied in the order they are defined. If unspecified, the default filter order is applied. Default filter order is:
- envoy.filters.http.health_check
- envoy.filters.http.fault
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.custom_response
- envoy.filters.http.router
Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. |
+| `backendTLS` | _[BackendTLSConfig](#backendtlsconfig)_ | false | BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends. These settings are applied on backends for which TLS policies are specified. |
+| `ipFamily` | _[IPFamily](#ipfamily)_ | false | IPFamily specifies the IP family for the EnvoyProxy fleet. This setting only affects the Gateway listener port and does not impact other aspects of the Envoy proxy configuration. If not specified, the system will operate as follows: - It defaults to IPv4 only. - IPv6 and dual-stack environments are not supported in this default configuration. Note: To enable IPv6 or dual-stack functionality, explicit configuration is required. |
+
+
+#### EnvoyProxyStatus
+
+
+
+EnvoyProxyStatus defines the observed state of EnvoyProxy. This type is not implemented
+until https://github.com/envoyproxy/gateway/issues/1007 is fixed.
+
+_Appears in:_
+- [EnvoyProxy](#envoyproxy)
+
+
+
+#### EnvoyResourceType
+
+_Underlying type:_ _string_
+
+EnvoyResourceType specifies the type URL of the Envoy resource.
+
+_Appears in:_
+- [EnvoyJSONPatchConfig](#envoyjsonpatchconfig)
+
+| Value | Description |
+| ----- | ----------- |
+| `type.googleapis.com/envoy.config.listener.v3.Listener` | ListenerEnvoyResourceType defines the Type URL of the Listener resource |
+| `type.googleapis.com/envoy.config.route.v3.RouteConfiguration` | RouteConfigurationEnvoyResourceType defines the Type URL of the RouteConfiguration resource |
+| `type.googleapis.com/envoy.config.cluster.v3.Cluster` | ClusterEnvoyResourceType defines the Type URL of the Cluster resource |
+| `type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment` | ClusterLoadAssignmentEnvoyResourceType defines the Type URL of the ClusterLoadAssignment resource |
+
+
+#### ExtAuth
+
+
+
+ExtAuth defines the configuration for External Authorization.
+
+_Appears in:_
+- [SecurityPolicySpec](#securitypolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `grpc` | _[GRPCExtAuthService](#grpcextauthservice)_ | true | GRPC defines the gRPC External Authorization service. Either GRPCService or HTTPService must be specified, and only one of them can be provided. |
+| `http` | _[HTTPExtAuthService](#httpextauthservice)_ | true | HTTP defines the HTTP External Authorization service. Either GRPCService or HTTPService must be specified, and only one of them can be provided. |
+| `headersToExtAuth` | _string array_ | false | HeadersToExtAuth defines the client request headers that will be included in the request to the external authorization service. Note: If not specified, the default behavior for gRPC and HTTP external authorization services is different due to backward compatibility reasons. All headers will be included in the check request to a gRPC authorization server. Only the following headers will be included in the check request to an HTTP authorization server: Host, Method, Path, Content-Length, and Authorization. And these headers will always be included to the check request to an HTTP authorization server by default, no matter whether they are specified in HeadersToExtAuth or not. |
+| `failOpen` | _boolean_ | false | FailOpen is a switch used to control the behavior when a response from the External Authorization service cannot be obtained. If FailOpen is set to true, the system allows the traffic to pass through. Otherwise, if it is set to false or not set (defaulting to false), the system blocks the traffic and returns a HTTP 5xx error, reflecting a fail-closed approach. This setting determines whether to prioritize accessibility over strict security in case of authorization service failure. |
+| `recomputeRoute` | _boolean_ | false | RecomputeRoute clears the route cache and recalculates the routing decision. This field must be enabled if the headers added or modified by the ExtAuth are used for route matching decisions. If the recomputation selects a new route, features targeting the new matched route will be applied. |
+
+
+#### ExtProc
+
+
+
+ExtProc defines the configuration for External Processing filter.
+
+_Appears in:_
+- [EnvoyExtensionPolicySpec](#envoyextensionpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+| `messageTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | MessageTimeout is the timeout for a response to be returned from the external processor Default: 200ms |
+| `failOpen` | _boolean_ | false | FailOpen defines if requests or responses that cannot be processed due to connectivity to the external processor are terminated or passed-through. Default: false |
+| `processingMode` | _[ExtProcProcessingMode](#extprocprocessingmode)_ | false | ProcessingMode defines how request and response body is processed Default: header and body are not sent to the external processor |
+
+
+#### ExtProcBodyProcessingMode
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [ProcessingModeOptions](#processingmodeoptions)
+
+| Value | Description |
+| ----- | ----------- |
+| `Streamed` | StreamedExtProcBodyProcessingMode will stream the body to the server in pieces as they arrive at the proxy. |
+| `Buffered` | BufferedExtProcBodyProcessingMode will buffer the message body in memory and send the entire body at once. If the body exceeds the configured buffer limit, then the downstream system will receive an error. |
+| `BufferedPartial` | BufferedPartialExtBodyHeaderProcessingMode will buffer the message body in memory and send the entire body in one chunk. If the body exceeds the configured buffer limit, then the body contents up to the buffer limit will be sent. |
+
+
+#### ExtProcProcessingMode
+
+
+
+ExtProcProcessingMode defines if and how headers and bodies are sent to the service.
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/processing_mode.proto#envoy-v3-api-msg-extensions-filters-http-ext-proc-v3-processingmode
+
+_Appears in:_
+- [ExtProc](#extproc)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `request` | _[ProcessingModeOptions](#processingmodeoptions)_ | false | Defines processing mode for requests. If present, request headers are sent. Request body is processed according to the specified mode. |
+| `response` | _[ProcessingModeOptions](#processingmodeoptions)_ | false | Defines processing mode for responses. If present, response headers are sent. Response body is processed according to the specified mode. |
+
+
+#### ExtensionAPISettings
+
+
+
+ExtensionAPISettings defines the settings specific to Gateway API Extensions.
+
+_Appears in:_
+- [EnvoyGateway](#envoygateway)
+- [EnvoyGatewaySpec](#envoygatewayspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `enableEnvoyPatchPolicy` | _boolean_ | true | EnableEnvoyPatchPolicy enables Envoy Gateway to reconcile and implement the EnvoyPatchPolicy resources. |
+| `enableBackend` | _boolean_ | true | EnableBackend enables Envoy Gateway to reconcile and implement the Backend resources. |
+
+
+#### ExtensionHooks
+
+
+
+ExtensionHooks defines extension hooks across all supported runners
+
+_Appears in:_
+- [ExtensionManager](#extensionmanager)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `xdsTranslator` | _[XDSTranslatorHooks](#xdstranslatorhooks)_ | true | XDSTranslator defines all the supported extension hooks for the xds-translator runner |
+
+
+#### ExtensionManager
+
+
+
+ExtensionManager defines the configuration for registering an extension manager to
+the Envoy Gateway control plane.
+
+_Appears in:_
+- [EnvoyGateway](#envoygateway)
+- [EnvoyGatewaySpec](#envoygatewayspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `resources` | _[GroupVersionKind](#groupversionkind) array_ | false | Resources defines the set of K8s resources the extension will handle as route filter resources |
+| `policyResources` | _[GroupVersionKind](#groupversionkind) array_ | false | PolicyResources defines the set of K8S resources the extension server will handle as directly attached GatewayAPI policies |
+| `hooks` | _[ExtensionHooks](#extensionhooks)_ | true | Hooks defines the set of hooks the extension supports |
+| `service` | _[ExtensionService](#extensionservice)_ | true | Service defines the configuration of the extension service that the Envoy Gateway Control Plane will call through extension hooks. |
+
+
+#### ExtensionService
+
+
+
+ExtensionService defines the configuration for connecting to a registered extension service.
+
+_Appears in:_
+- [ExtensionManager](#extensionmanager)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `fqdn` | _[FQDNEndpoint](#fqdnendpoint)_ | false | FQDN defines a FQDN endpoint |
+| `ip` | _[IPEndpoint](#ipendpoint)_ | false | IP defines an IP endpoint. Supports both IPv4 and IPv6 addresses. |
+| `unix` | _[UnixSocket](#unixsocket)_ | false | Unix defines the unix domain socket endpoint |
+| `host` | _string_ | false | Host define the extension service hostname. Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix) |
+| `port` | _integer_ | false | Port defines the port the extension service is exposed on. Deprecated: use the appropriate transport attribute instead (FQDN,IP,Unix) |
+| `tls` | _[ExtensionTLS](#extensiontls)_ | false | TLS defines TLS configuration for communication between Envoy Gateway and the extension service. |
+
+
+#### ExtensionTLS
+
+
+
+ExtensionTLS defines the TLS configuration when connecting to an extension service
+
+_Appears in:_
+- [ExtensionService](#extensionservice)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `certificateRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | CertificateRef contains a references to objects (Kubernetes objects or otherwise) that contains a TLS certificate and private keys. These certificates are used to establish a TLS handshake to the extension server.
CertificateRef can only reference a Kubernetes Secret at this time. |
+
+
+#### FQDNEndpoint
+
+
+
+FQDNEndpoint describes TCP/UDP socket address, corresponding to Envoy's Socket Address
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-socketaddress
+
+_Appears in:_
+- [BackendEndpoint](#backendendpoint)
+- [ExtensionService](#extensionservice)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `hostname` | _string_ | true | Hostname defines the FQDN hostname of the backend endpoint. |
+| `port` | _integer_ | true | Port defines the port of the backend endpoint. |
+
+
+#### FaultInjection
+
+
+
+FaultInjection defines the fault injection policy to be applied. This configuration can be used to
+inject delays and abort requests to mimic failure scenarios such as service failures and overloads
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `delay` | _[FaultInjectionDelay](#faultinjectiondelay)_ | false | If specified, a delay will be injected into the request. |
+| `abort` | _[FaultInjectionAbort](#faultinjectionabort)_ | false | If specified, the request will be aborted if it meets the configuration criteria. |
+
+
+#### FaultInjectionAbort
+
+
+
+FaultInjectionAbort defines the abort fault injection configuration
+
+_Appears in:_
+- [FaultInjection](#faultinjection)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `httpStatus` | _integer_ | false | StatusCode specifies the HTTP status code to be returned |
+| `grpcStatus` | _integer_ | false | GrpcStatus specifies the GRPC status code to be returned |
+| `percentage` | _float_ | false | Percentage specifies the percentage of requests to be aborted. Default 100%, if set 0, no requests will be aborted. Accuracy to 0.0001%. |
+
+
+#### FaultInjectionDelay
+
+
+
+FaultInjectionDelay defines the delay fault injection configuration
+
+_Appears in:_
+- [FaultInjection](#faultinjection)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `fixedDelay` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | FixedDelay specifies the fixed delay duration |
+| `percentage` | _float_ | false | Percentage specifies the percentage of requests to be delayed. Default 100%, if set 0, no requests will be delayed. Accuracy to 0.0001%. |
+
+
+#### FileEnvoyProxyAccessLog
+
+
+
+
+
+_Appears in:_
+- [ProxyAccessLogSink](#proxyaccesslogsink)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `path` | _string_ | true | Path defines the file path used to expose envoy access log(e.g. /dev/stdout). |
+
+
+#### FilterPosition
+
+
+
+FilterPosition defines the position of an Envoy HTTP filter in the filter chain.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _[EnvoyFilter](#envoyfilter)_ | true | Name of the filter. |
+| `before` | _[EnvoyFilter](#envoyfilter)_ | true | Before defines the filter that should come before the filter. Only one of Before or After must be set. |
+| `after` | _[EnvoyFilter](#envoyfilter)_ | true | After defines the filter that should come after the filter. Only one of Before or After must be set. |
+
+
+#### GRPCActiveHealthChecker
+
+
+
+GRPCActiveHealthChecker defines the settings of the GRPC health check.
+
+_Appears in:_
+- [ActiveHealthCheck](#activehealthcheck)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `service` | _string_ | false | Service to send in the health check request. If this is not specified, then the health check request applies to the entire server and not to a specific service. |
+
+
+#### GRPCExtAuthService
+
+
+
+GRPCExtAuthService defines the gRPC External Authorization service
+The authorization request message is defined in
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto
+
+_Appears in:_
+- [ExtAuth](#extauth)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+
+
+#### Gateway
+
+
+
+Gateway defines the desired Gateway API configuration of Envoy Gateway.
+
+_Appears in:_
+- [EnvoyGateway](#envoygateway)
+- [EnvoyGatewaySpec](#envoygatewayspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `controllerName` | _string_ | false | ControllerName defines the name of the Gateway API controller. If unspecified, defaults to "gateway.envoyproxy.io/gatewayclass-controller". See the following for additional details: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass |
+
+
+#### GlobalRateLimit
+
+
+
+GlobalRateLimit defines global rate limit configuration.
+
+_Appears in:_
+- [RateLimitSpec](#ratelimitspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `rules` | _[RateLimitRule](#ratelimitrule) array_ | true | Rules are a list of RateLimit selectors and limits. Each rule and its associated limit is applied in a mutually exclusive way. If a request matches multiple rules, each of their associated limits get applied, so a single request might increase the rate limit counters for multiple rules if selected. The rate limit service will return a logical OR of the individual rate limit decisions of all matching rules. For example, if a request matches two rules, one rate limited and one not, the final decision will be to rate limit the request. |
+
+
+#### GroupVersionKind
+
+
+
+GroupVersionKind unambiguously identifies a Kind.
+It can be converted to k8s.io/apimachinery/pkg/runtime/schema.GroupVersionKind
+
+_Appears in:_
+- [ExtensionManager](#extensionmanager)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `group` | _string_ | true | |
+| `version` | _string_ | true | |
+| `kind` | _string_ | true | |
+
+
+#### GzipCompressor
+
+
+
+GzipCompressor defines the config for the Gzip compressor.
+The default values can be found here:
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/compression/gzip/compressor/v3/gzip.proto#extension-envoy-compression-gzip-compressor
+
+_Appears in:_
+- [Compression](#compression)
+
+
+
+#### HTTP10Settings
+
+
+
+HTTP10Settings provides HTTP/1.0 configuration on the listener.
+
+_Appears in:_
+- [HTTP1Settings](#http1settings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `useDefaultHost` | _boolean_ | false | UseDefaultHost defines if the HTTP/1.0 request is missing the Host header, then the hostname associated with the listener should be injected into the request. If this is not set and an HTTP/1.0 request arrives without a host, then it will be rejected. |
+
+
+#### HTTP1Settings
+
+
+
+HTTP1Settings provides HTTP/1 configuration on the listener.
+
+_Appears in:_
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `enableTrailers` | _boolean_ | false | EnableTrailers defines if HTTP/1 trailers should be proxied by Envoy. |
+| `preserveHeaderCase` | _boolean_ | false | PreserveHeaderCase defines if Envoy should preserve the letter case of headers. By default, Envoy will lowercase all the headers. |
+| `http10` | _[HTTP10Settings](#http10settings)_ | false | HTTP10 turns on support for HTTP/1.0 and HTTP/0.9 requests. |
+
+
+#### HTTP2Settings
+
+
+
+HTTP2Settings provides HTTP/2 configuration for listeners and backends.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `initialStreamWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams. If not set, the default value is 64 KiB(64*1024). |
+| `initialConnectionWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. If not set, the default value is 1 MiB. |
+| `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. If not set, the default value is 100. |
+| `onInvalidMessage` | _[InvalidMessageAction](#invalidmessageaction)_ | false | OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error It's recommended for L2 Envoy deployments to set this value to TerminateStream. https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two Default: TerminateConnection |
+
+
+#### HTTP3Settings
+
+
+
+HTTP3Settings provides HTTP/3 configuration on the listener.
+
+_Appears in:_
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+
+
+
+#### HTTPActiveHealthChecker
+
+
+
+HTTPActiveHealthChecker defines the settings of http health check.
+
+_Appears in:_
+- [ActiveHealthCheck](#activehealthcheck)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `path` | _string_ | true | Path defines the HTTP path that will be requested during health checking. |
+| `method` | _string_ | false | Method defines the HTTP method used for health checking. Defaults to GET |
+| `expectedStatuses` | _[HTTPStatus](#httpstatus) array_ | false | ExpectedStatuses defines a list of HTTP response statuses considered healthy. Defaults to 200 only |
+| `expectedResponse` | _[ActiveHealthCheckPayload](#activehealthcheckpayload)_ | false | ExpectedResponse defines a list of HTTP expected responses to match. |
+
+
+#### HTTPClientTimeout
+
+
+
+
+
+_Appears in:_
+- [ClientTimeout](#clienttimeout)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `requestReceivedTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | RequestReceivedTimeout is the duration envoy waits for the complete request reception. This timer starts upon request initiation and stops when either the last byte of the request is sent upstream or when the response begins. |
+| `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | IdleTimeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. Default: 1 hour. |
+
+
+#### HTTPDirectResponseFilter
+
+
+
+HTTPDirectResponseFilter defines the configuration to return a fixed response.
+
+_Appears in:_
+- [HTTPRouteFilterSpec](#httproutefilterspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `contentType` | _string_ | false | Content Type of the response. This will be set in the Content-Type header. |
+| `body` | _[CustomResponseBody](#customresponsebody)_ | false | Body of the Response |
+| `statusCode` | _integer_ | false | Status Code of the HTTP response If unset, defaults to 200. |
+
+
+#### HTTPExtAuthService
+
+
+
+HTTPExtAuthService defines the HTTP External Authorization service
+
+_Appears in:_
+- [ExtAuth](#extauth)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+| `path` | _string_ | true | Path is the path of the HTTP External Authorization service. If path is specified, the authorization request will be sent to that path, or else the authorization request will be sent to the root path. |
+| `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added to the original client request before sending it to the backend server. Note that coexisting headers will be overridden. If not specified, no authorization response headers will be added to the original client request. |
+
+
+#### HTTPHostnameModifier
+
+
+
+
+
+_Appears in:_
+- [HTTPURLRewriteFilter](#httpurlrewritefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[HTTPHostnameModifierType](#httphostnamemodifiertype)_ | true | |
+| `header` | _string_ | false | Header is the name of the header whose value would be used to rewrite the Host header |
+
+
+#### HTTPHostnameModifierType
+
+_Underlying type:_ _string_
+
+HTTPPathModifierType defines the type of Hostname rewrite.
+
+_Appears in:_
+- [HTTPHostnameModifier](#httphostnamemodifier)
+
+| Value | Description |
+| ----- | ----------- |
+| `Header` | HeaderHTTPHostnameModifier indicates that the Host header value would be replaced with the value of the header specified in header. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-header |
+| `Backend` | BackendHTTPHostnameModifier indicates that the Host header value would be replaced by the DNS name of the backend if it exists. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-auto-host-rewrite |
+
+
+#### HTTPPathModifier
+
+
+
+
+
+_Appears in:_
+- [HTTPURLRewriteFilter](#httpurlrewritefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[HTTPPathModifierType](#httppathmodifiertype)_ | true | |
+| `replaceRegexMatch` | _[ReplaceRegexMatch](#replaceregexmatch)_ | false | ReplaceRegexMatch defines a path regex rewrite. The path portions matched by the regex pattern are replaced by the defined substitution. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-regex-rewrite Some examples: (1) replaceRegexMatch: pattern: ^/service/([^/]+)(/.*)$ substitution: \2/instance/\1 Would transform /service/foo/v1/api into /v1/api/instance/foo. (2) replaceRegexMatch: pattern: one substitution: two Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/two/zzz. (3) replaceRegexMatch: pattern: ^(.*?)one(.*)$ substitution: \1two\2 Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/one/zzz. (3) replaceRegexMatch: pattern: (?i)/xxx/ substitution: /yyy/ Would transform path /aaa/XxX/bbb into /aaa/yyy/bbb (case-insensitive). |
+
+
+#### HTTPPathModifierType
+
+_Underlying type:_ _string_
+
+HTTPPathModifierType defines the type of path redirect or rewrite.
+
+_Appears in:_
+- [HTTPPathModifier](#httppathmodifier)
+
+| Value | Description |
+| ----- | ----------- |
+| `ReplaceRegexMatch` | RegexHTTPPathModifier This type of modifier indicates that the portions of the path that match the specified regex would be substituted with the specified substitution value https://www.envoyproxy.io/docs/envoy/latest/api-v3/type/matcher/v3/regex.proto#type-matcher-v3-regexmatchandsubstitute |
+
+
+#### HTTPRouteFilter
+
+
+
+HTTPRouteFilter is a custom Envoy Gateway HTTPRouteFilter which provides extended
+traffic processing options such as path regex rewrite, direct response and more.
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`HTTPRouteFilter`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[HTTPRouteFilterSpec](#httproutefilterspec)_ | true | Spec defines the desired state of HTTPRouteFilter. |
+
+
+#### HTTPRouteFilterSpec
+
+
+
+HTTPRouteFilterSpec defines the desired state of HTTPRouteFilter.
+
+_Appears in:_
+- [HTTPRouteFilter](#httproutefilter)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `urlRewrite` | _[HTTPURLRewriteFilter](#httpurlrewritefilter)_ | false | |
+| `directResponse` | _[HTTPDirectResponseFilter](#httpdirectresponsefilter)_ | false | |
+
+
+#### HTTPStatus
+
+_Underlying type:_ _integer_
+
+HTTPStatus defines the http status code.
+
+_Appears in:_
+- [HTTPActiveHealthChecker](#httpactivehealthchecker)
+- [RetryOn](#retryon)
+
+
+
+#### HTTPTimeout
+
+
+
+
+
+_Appears in:_
+- [Timeout](#timeout)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `connectionIdleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. Default: 1 hour. |
+| `maxConnectionDuration` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The maximum duration of an HTTP connection. Default: unlimited. |
+| `requestTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | RequestTimeout is the time until which entire response is received from the upstream. |
+
+
+#### HTTPURLRewriteFilter
+
+
+
+HTTPURLRewriteFilter define rewrites of HTTP URL components such as path and host
+
+_Appears in:_
+- [HTTPRouteFilterSpec](#httproutefilterspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `hostname` | _[HTTPHostnameModifier](#httphostnamemodifier)_ | false | Hostname is the value to be used to replace the Host header value during forwarding. |
+| `path` | _[HTTPPathModifier](#httppathmodifier)_ | false | Path defines a path rewrite. |
+
+
+#### HTTPWasmCodeSource
+
+
+
+HTTPWasmCodeSource defines the HTTP URL containing the Wasm code.
+
+_Appears in:_
+- [WasmCodeSource](#wasmcodesource)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `url` | _string_ | true | URL is the URL containing the Wasm code. |
+| `sha256` | _string_ | false | SHA256 checksum that will be used to verify the Wasm code.
If not specified, Envoy Gateway will not verify the downloaded Wasm code. kubebuilder:validation:Pattern=`^[a-f0-9]\{64\}$` |
+
+
+#### Header
+
+
+
+Header defines the header hashing configuration for consistent hash based
+load balancing.
+
+_Appears in:_
+- [ConsistentHash](#consistenthash)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | true | Name of the header to hash. |
+
+
+#### HeaderMatch
+
+
+
+HeaderMatch defines the match attributes within the HTTP Headers of the request.
+
+_Appears in:_
+- [RateLimitSelectCondition](#ratelimitselectcondition)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[HeaderMatchType](#headermatchtype)_ | false | Type specifies how to match against the value of the header. |
+| `name` | _string_ | true | Name of the HTTP header. |
+| `value` | _string_ | false | Value within the HTTP header. Due to the case-insensitivity of header names, "foo" and "Foo" are considered equivalent. Do not set this field when Type="Distinct", implying matching on any/all unique values within the header. |
+| `invert` | _boolean_ | false | Invert specifies whether the value match result will be inverted. Do not set this field when Type="Distinct", implying matching on any/all unique values within the header. |
+
+
+#### HeaderMatchType
+
+_Underlying type:_ _string_
+
+HeaderMatchType specifies the semantics of how HTTP header values should be compared.
+Valid HeaderMatchType values are "Exact", "RegularExpression", and "Distinct".
+
+_Appears in:_
+- [HeaderMatch](#headermatch)
+
+| Value | Description |
+| ----- | ----------- |
+| `Exact` | HeaderMatchExact matches the exact value of the Value field against the value of the specified HTTP Header. |
+| `RegularExpression` | HeaderMatchRegularExpression matches a regular expression against the value of the specified HTTP Header. The regex string must adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax. |
+| `Distinct` | HeaderMatchDistinct matches any and all possible unique values encountered in the specified HTTP Header. Note that each unique value will receive its own rate limit bucket. Note: This is only supported for Global Rate Limits. |
+
+
+#### HeaderSettings
+
+
+
+HeaderSettings provides configuration options for headers on the listener.
+
+_Appears in:_
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `enableEnvoyHeaders` | _boolean_ | false | EnableEnvoyHeaders configures Envoy Proxy to add the "X-Envoy-" headers to requests and responses. |
+| `disableRateLimitHeaders` | _boolean_ | false | DisableRateLimitHeaders configures Envoy Proxy to omit the "X-RateLimit-" response headers when rate limiting is enabled. |
+| `xForwardedClientCert` | _[XForwardedClientCert](#xforwardedclientcert)_ | false | XForwardedClientCert configures how Envoy Proxy handle the x-forwarded-client-cert (XFCC) HTTP header.
x-forwarded-client-cert (XFCC) is an HTTP header used to forward the certificate information of part or all of the clients or proxies that a request has flowed through, on its way from the client to the server.
Envoy proxy may choose to sanitize/append/forward the XFCC header before proxying the request.
If not set, the default behavior is sanitizing the XFCC header. |
+| `withUnderscoresAction` | _[WithUnderscoresAction](#withunderscoresaction)_ | false | WithUnderscoresAction configures the action to take when an HTTP header with underscores is encountered. The default action is to reject the request. |
+| `preserveXRequestID` | _boolean_ | false | PreserveXRequestID configures Envoy to keep the X-Request-ID header if passed for a request that is edge (Edge request is the request from external clients to front Envoy) and not reset it, which is the current Envoy behaviour. It defaults to false. |
+| `earlyRequestHeaders` | _[HTTPHeaderFilter](#httpheaderfilter)_ | false | EarlyRequestHeaders defines settings for early request header modification, before envoy performs routing, tracing and built-in header manipulation. |
+
+
+#### HealthCheck
+
+
+
+HealthCheck configuration to decide which endpoints
+are healthy and can be used for routing.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `active` | _[ActiveHealthCheck](#activehealthcheck)_ | false | Active health check configuration |
+| `passive` | _[PassiveHealthCheck](#passivehealthcheck)_ | false | Passive passive check configuration |
+
+
+#### HealthCheckSettings
+
+
+
+HealthCheckSettings provides HealthCheck configuration on the HTTP/HTTPS listener.
+
+_Appears in:_
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `path` | _string_ | true | Path specifies the HTTP path to match on for health check requests. |
+
+
+#### IPEndpoint
+
+
+
+IPEndpoint describes TCP/UDP socket address, corresponding to Envoy's Socket Address
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-socketaddress
+
+_Appears in:_
+- [BackendEndpoint](#backendendpoint)
+- [ExtensionService](#extensionservice)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `address` | _string_ | true | Address defines the IP address of the backend endpoint. Supports both IPv4 and IPv6 addresses. |
+| `port` | _integer_ | true | Port defines the port of the backend endpoint. |
+
+
+#### IPFamily
+
+_Underlying type:_ _string_
+
+IPFamily defines the IP family to use for the Envoy proxy.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Value | Description |
+| ----- | ----------- |
+| `IPv4` | IPv4 defines the IPv4 family. |
+| `IPv6` | IPv6 defines the IPv6 family. |
+| `DualStack` | DualStack defines the dual-stack family. When set to DualStack, Envoy proxy will listen on both IPv4 and IPv6 addresses for incoming client traffic, enabling support for both IP protocol versions. |
+
+
+#### ImagePullPolicy
+
+_Underlying type:_ _string_
+
+ImagePullPolicy defines the policy to use when pulling an OIC image.
+
+_Appears in:_
+- [WasmCodeSource](#wasmcodesource)
+
+| Value | Description |
+| ----- | ----------- |
+| `IfNotPresent` | ImagePullPolicyIfNotPresent will only pull the image if it does not already exist in the EG cache. |
+| `Always` | ImagePullPolicyAlways will pull the image when the EnvoyExtension resource version changes. Note: EG does not update the Wasm module every time an Envoy proxy requests the Wasm module. |
+
+
+#### ImageWasmCodeSource
+
+
+
+ImageWasmCodeSource defines the OCI image containing the Wasm code.
+
+_Appears in:_
+- [WasmCodeSource](#wasmcodesource)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `url` | _string_ | true | URL is the URL of the OCI image. URL can be in the format of `registry/image:tag` or `registry/image@sha256:digest`. |
+| `sha256` | _string_ | false | SHA256 checksum that will be used to verify the OCI image.
It must match the digest of the OCI image.
If not specified, Envoy Gateway will not verify the downloaded OCI image. kubebuilder:validation:Pattern=`^[a-f0-9]\{64\}$` |
+| `pullSecretRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | false | PullSecretRef is a reference to the secret containing the credentials to pull the image. Only support Kubernetes Secret resource from the same namespace. |
+
+
+#### InfrastructureProviderType
+
+_Underlying type:_ _string_
+
+InfrastructureProviderType defines the types of custom infrastructure providers supported by Envoy Gateway.
+
+_Appears in:_
+- [EnvoyGatewayInfrastructureProvider](#envoygatewayinfrastructureprovider)
+
+| Value | Description |
+| ----- | ----------- |
+| `Host` | InfrastructureProviderTypeHost defines the "Host" provider. |
+
+
+#### InvalidMessageAction
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [HTTP2Settings](#http2settings)
+
+| Value | Description |
+| ----- | ----------- |
+| `TerminateConnection` | |
+| `TerminateStream` | |
+
+
+#### JSONPatchOperation
+
+
+
+JSONPatchOperation defines the JSON Patch Operation as defined in
+https://datatracker.ietf.org/doc/html/rfc6902
+
+_Appears in:_
+- [EnvoyJSONPatchConfig](#envoyjsonpatchconfig)
+- [ProxyBootstrap](#proxybootstrap)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `op` | _[JSONPatchOperationType](#jsonpatchoperationtype)_ | true | Op is the type of operation to perform |
+| `path` | _string_ | false | Path is a JSONPointer expression. Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. It specifies the location of the target document/field where the operation will be performed |
+| `jsonPath` | _string_ | false | JSONPath is a JSONPath expression. Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details. It produces one or more JSONPointer expressions based on the given JSON document. If no JSONPointer is found, it will result in an error. If the 'Path' property is also set, it will be appended to the resulting JSONPointer expressions from the JSONPath evaluation. This is useful when creating a property that does not yet exist in the JSON document. The final JSONPointer expressions specifies the locations in the target document/field where the operation will be applied. |
+| `from` | _string_ | false | From is the source location of the value to be copied or moved. Only valid for move or copy operations Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
+| `value` | _[JSON](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#json-v1-apiextensions-k8s-io)_ | false | Value is the new value of the path location. The value is only used by the `add` and `replace` operations. |
+
+
+#### JSONPatchOperationType
+
+_Underlying type:_ _string_
+
+JSONPatchOperationType specifies the JSON Patch operations that can be performed.
+
+_Appears in:_
+- [JSONPatchOperation](#jsonpatchoperation)
+
+
+
+#### JWT
+
+
+
+JWT defines the configuration for JSON Web Token (JWT) authentication.
+
+_Appears in:_
+- [SecurityPolicySpec](#securitypolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `optional` | _boolean_ | true | Optional determines whether a missing JWT is acceptable, defaulting to false if not specified. Note: Even if optional is set to true, JWT authentication will still fail if an invalid JWT is presented. |
+| `providers` | _[JWTProvider](#jwtprovider) array_ | true | Providers defines the JSON Web Token (JWT) authentication provider type. When multiple JWT providers are specified, the JWT is considered valid if any of the providers successfully validate the JWT. For additional details, see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html. |
+
+
+#### JWTClaim
+
+
+
+JWTClaim specifies a claim in a JWT token.
+
+_Appears in:_
+- [JWTPrincipal](#jwtprincipal)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | true | Name is the name of the claim. If it is a nested claim, use a dot (.) separated string as the name to represent the full path to the claim. For example, if the claim is in the "department" field in the "organization" field, the name should be "organization.department". |
+| `valueType` | _[JWTClaimValueType](#jwtclaimvaluetype)_ | false | ValueType is the type of the claim value. Only String and StringArray types are supported for now. |
+| `values` | _string array_ | true | Values are the values that the claim must match. If the claim is a string type, the specified value must match exactly. If the claim is a string array type, the specified value must match one of the values in the array. If multiple values are specified, one of the values must match for the rule to match. |
+
+
+#### JWTClaimValueType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [JWTClaim](#jwtclaim)
+
+| Value | Description |
+| ----- | ----------- |
+| `String` | |
+| `StringArray` | |
+
+
+#### JWTExtractor
+
+
+
+JWTExtractor defines a custom JWT token extraction from HTTP request.
+If specified, Envoy will extract the JWT token from the listed extractors (headers, cookies, or params) and validate each of them.
+If any value extracted is found to be an invalid JWT, a 401 error will be returned.
+
+_Appears in:_
+- [JWTProvider](#jwtprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `headers` | _[JWTHeaderExtractor](#jwtheaderextractor) array_ | false | Headers represents a list of HTTP request headers to extract the JWT token from. |
+| `cookies` | _string array_ | false | Cookies represents a list of cookie names to extract the JWT token from. |
+| `params` | _string array_ | false | Params represents a list of query parameters to extract the JWT token from. |
+
+
+#### JWTHeaderExtractor
+
+
+
+JWTHeaderExtractor defines an HTTP header location to extract JWT token
+
+_Appears in:_
+- [JWTExtractor](#jwtextractor)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | true | Name is the HTTP header name to retrieve the token |
+| `valuePrefix` | _string_ | false | ValuePrefix is the prefix that should be stripped before extracting the token. The format would be used by Envoy like "\{ValuePrefix\}". For example, "Authorization: Bearer ", then the ValuePrefix="Bearer " with a space at the end. |
+
+
+#### JWTPrincipal
+
+
+
+JWTPrincipal specifies the client identity of a request based on the JWT claims and scopes.
+At least one of the claims or scopes must be specified.
+Claims and scopes are And-ed together if both are specified.
+
+_Appears in:_
+- [Principal](#principal)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `provider` | _string_ | true | Provider is the name of the JWT provider that used to verify the JWT token. In order to use JWT claims for authorization, you must configure the JWT authentication with the same provider in the same `SecurityPolicy`. |
+| `claims` | _[JWTClaim](#jwtclaim) array_ | false | Claims are the claims in a JWT token.
If multiple claims are specified, all claims must match for the rule to match. For example, if there are two claims: one for the audience and one for the issuer, the rule will match only if both the audience and the issuer match. |
+| `scopes` | _[JWTScope](#jwtscope) array_ | false | Scopes are a special type of claim in a JWT token that represents the permissions of the client.
The value of the scopes field should be a space delimited string that is expected in the scope parameter, as defined in RFC 6749: https://datatracker.ietf.org/doc/html/rfc6749#page-23.
If multiple scopes are specified, all scopes must match for the rule to match. |
+
+
+#### JWTProvider
+
+
+
+JWTProvider defines how a JSON Web Token (JWT) can be verified.
+
+_Appears in:_
+- [JWT](#jwt)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | true | Name defines a unique name for the JWT provider. A name can have a variety of forms, including RFC1123 subdomains, RFC 1123 labels, or RFC 1035 labels. |
+| `issuer` | _string_ | false | Issuer is the principal that issued the JWT and takes the form of a URL or email address. For additional details, see https://tools.ietf.org/html/rfc7519#section-4.1.1 for URL format and https://rfc-editor.org/rfc/rfc5322.html for email format. If not provided, the JWT issuer is not checked. |
+| `audiences` | _string array_ | false | Audiences is a list of JWT audiences allowed access. For additional details, see https://tools.ietf.org/html/rfc7519#section-4.1.3. If not provided, JWT audiences are not checked. |
+| `remoteJWKS` | _[RemoteJWKS](#remotejwks)_ | true | RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote HTTP/HTTPS endpoint. |
+| `claimToHeaders` | _[ClaimToHeader](#claimtoheader) array_ | false | ClaimToHeaders is a list of JWT claims that must be extracted into HTTP request headers For examples, following config: The claim must be of type; string, int, double, bool. Array type claims are not supported |
+| `recomputeRoute` | _boolean_ | false | RecomputeRoute clears the route cache and recalculates the routing decision. This field must be enabled if the headers generated from the claim are used for route matching decisions. If the recomputation selects a new route, features targeting the new matched route will be applied. |
+| `extractFrom` | _[JWTExtractor](#jwtextractor)_ | false | ExtractFrom defines different ways to extract the JWT token from HTTP request. If empty, it defaults to extract JWT token from the Authorization HTTP request header using Bearer schema or access_token from query parameters. |
+
+
+#### JWTScope
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [JWTPrincipal](#jwtprincipal)
+
+
+
+#### KubernetesContainerSpec
+
+
+
+KubernetesContainerSpec defines the desired state of the Kubernetes container resource.
+
+_Appears in:_
+- [KubernetesDaemonSetSpec](#kubernetesdaemonsetspec)
+- [KubernetesDeploymentSpec](#kubernetesdeploymentspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `env` | _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) array_ | false | List of environment variables to set in the container. |
+| `resources` | _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core)_ | false | Resources required by this container. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ |
+| `securityContext` | _[SecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#securitycontext-v1-core)_ | false | SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ |
+| `image` | _string_ | false | Image specifies the EnvoyProxy container image to be used, instead of the default image. |
+| `volumeMounts` | _[VolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#volumemount-v1-core) array_ | false | VolumeMounts are volumes to mount into the container's filesystem. Cannot be updated. |
+
+
+#### KubernetesDaemonSetSpec
+
+
+
+KubernetesDaemonSetSpec defines the desired state of the Kubernetes daemonset resource.
+
+_Appears in:_
+- [EnvoyProxyKubernetesProvider](#envoyproxykubernetesprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `patch` | _[KubernetesPatchSpec](#kubernetespatchspec)_ | false | Patch defines how to perform the patch operation to daemonset |
+| `strategy` | _[DaemonSetUpdateStrategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#daemonsetupdatestrategy-v1-apps)_ | false | The daemonset strategy to use to replace existing pods with new ones. |
+| `pod` | _[KubernetesPodSpec](#kubernetespodspec)_ | false | Pod defines the desired specification of pod. |
+| `container` | _[KubernetesContainerSpec](#kubernetescontainerspec)_ | false | Container defines the desired specification of main container. |
+| `name` | _string_ | false | Name of the daemonSet. When unset, this defaults to an autogenerated name. |
+
+
+#### KubernetesDeployMode
+
+
+
+KubernetesDeployMode holds configuration for how to deploy managed resources such as the Envoy Proxy
+data plane fleet.
+
+_Appears in:_
+- [EnvoyGatewayKubernetesProvider](#envoygatewaykubernetesprovider)
+
+
+
+#### KubernetesDeploymentSpec
+
+
+
+KubernetesDeploymentSpec defines the desired state of the Kubernetes deployment resource.
+
+_Appears in:_
+- [EnvoyGatewayKubernetesProvider](#envoygatewaykubernetesprovider)
+- [EnvoyProxyKubernetesProvider](#envoyproxykubernetesprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `patch` | _[KubernetesPatchSpec](#kubernetespatchspec)_ | false | Patch defines how to perform the patch operation to deployment |
+| `replicas` | _integer_ | false | Replicas is the number of desired pods. Defaults to 1. |
+| `strategy` | _[DeploymentStrategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#deploymentstrategy-v1-apps)_ | false | The deployment strategy to use to replace existing pods with new ones. |
+| `pod` | _[KubernetesPodSpec](#kubernetespodspec)_ | false | Pod defines the desired specification of pod. |
+| `container` | _[KubernetesContainerSpec](#kubernetescontainerspec)_ | false | Container defines the desired specification of main container. |
+| `initContainers` | _[Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#container-v1-core) array_ | false | List of initialization containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ |
+| `name` | _string_ | false | Name of the deployment. When unset, this defaults to an autogenerated name. |
+
+
+#### KubernetesHorizontalPodAutoscalerSpec
+
+
+
+KubernetesHorizontalPodAutoscalerSpec defines Kubernetes Horizontal Pod Autoscaler settings of Envoy Proxy Deployment.
+When HPA is enabled, it is recommended that the value in `KubernetesDeploymentSpec.replicas` be removed, otherwise
+Envoy Gateway will revert back to this value every time reconciliation occurs.
+See k8s.io.autoscaling.v2.HorizontalPodAutoScalerSpec.
+
+_Appears in:_
+- [EnvoyProxyKubernetesProvider](#envoyproxykubernetesprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `minReplicas` | _integer_ | false | minReplicas is the lower limit for the number of replicas to which the autoscaler can scale down. It defaults to 1 replica. |
+| `maxReplicas` | _integer_ | true | maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. It cannot be less that minReplicas. |
+| `metrics` | _[MetricSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#metricspec-v2-autoscaling) array_ | false | metrics contains the specifications for which to use to calculate the desired replica count (the maximum replica count across all metrics will be used). If left empty, it defaults to being based on CPU utilization with average on 80% usage. |
+| `behavior` | _[HorizontalPodAutoscalerBehavior](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#horizontalpodautoscalerbehavior-v2-autoscaling)_ | false | behavior configures the scaling behavior of the target in both Up and Down directions (scaleUp and scaleDown fields respectively). If not set, the default HPAScalingRules for scale up and scale down are used. See k8s.io.autoscaling.v2.HorizontalPodAutoScalerBehavior. |
+
+
+#### KubernetesPatchSpec
+
+
+
+KubernetesPatchSpec defines how to perform the patch operation.
+Note that `value` can be an in-line YAML document, as can be seen in e.g. (the example of patching the Envoy proxy Deployment)[https://gateway.envoyproxy.io/docs/tasks/operations/customize-envoyproxy/#patching-deployment-for-envoyproxy].
+Note also that, currently, strings containing literal JSON are _rejected_.
+
+_Appears in:_
+- [KubernetesDaemonSetSpec](#kubernetesdaemonsetspec)
+- [KubernetesDeploymentSpec](#kubernetesdeploymentspec)
+- [KubernetesServiceSpec](#kubernetesservicespec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[MergeType](#mergetype)_ | false | Type is the type of merge operation to perform
By default, StrategicMerge is used as the patch type. |
+| `value` | _[JSON](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#json-v1-apiextensions-k8s-io)_ | true | Object contains the raw configuration for merged object |
+
+
+#### KubernetesPodDisruptionBudgetSpec
+
+
+
+KubernetesPodDisruptionBudgetSpec defines Kubernetes PodDisruptionBudget settings of Envoy Proxy Deployment.
+
+_Appears in:_
+- [EnvoyProxyKubernetesProvider](#envoyproxykubernetesprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `minAvailable` | _integer_ | false | MinAvailable specifies the minimum number of pods that must be available at all times during voluntary disruptions, such as node drains or updates. This setting ensures that your envoy proxy maintains a certain level of availability and resilience during maintenance operations. |
+
+
+#### KubernetesPodSpec
+
+
+
+KubernetesPodSpec defines the desired state of the Kubernetes pod resource.
+
+_Appears in:_
+- [KubernetesDaemonSetSpec](#kubernetesdaemonsetspec)
+- [KubernetesDeploymentSpec](#kubernetesdeploymentspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `annotations` | _object (keys:string, values:string)_ | false | Annotations are the annotations that should be appended to the pods. By default, no pod annotations are appended. |
+| `labels` | _object (keys:string, values:string)_ | false | Labels are the additional labels that should be tagged to the pods. By default, no additional pod labels are tagged. |
+| `securityContext` | _[PodSecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#podsecuritycontext-v1-core)_ | false | SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field. |
+| `affinity` | _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#affinity-v1-core)_ | false | If specified, the pod's scheduling constraints. |
+| `tolerations` | _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#toleration-v1-core) array_ | false | If specified, the pod's tolerations. |
+| `volumes` | _[Volume](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#volume-v1-core) array_ | false | Volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes |
+| `imagePullSecrets` | _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#localobjectreference-v1-core) array_ | false | ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod |
+| `nodeSelector` | _object (keys:string, values:string)_ | false | NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ |
+| `topologySpreadConstraints` | _[TopologySpreadConstraint](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#topologyspreadconstraint-v1-core) array_ | false | TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed. |
+
+
+#### KubernetesServiceSpec
+
+
+
+KubernetesServiceSpec defines the desired state of the Kubernetes service resource.
+
+_Appears in:_
+- [EnvoyProxyKubernetesProvider](#envoyproxykubernetesprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `annotations` | _object (keys:string, values:string)_ | false | Annotations that should be appended to the service. By default, no annotations are appended. |
+| `labels` | _object (keys:string, values:string)_ | false | Labels that should be appended to the service. By default, no labels are appended. |
+| `type` | _[ServiceType](#servicetype)_ | false | Type determines how the Service is exposed. Defaults to LoadBalancer. Valid options are ClusterIP, LoadBalancer and NodePort. "LoadBalancer" means a service will be exposed via an external load balancer (if the cloud provider supports it). "ClusterIP" means a service will only be accessible inside the cluster, via the cluster IP. "NodePort" means a service will be exposed on a static Port on all Nodes of the cluster. |
+| `loadBalancerClass` | _string_ | false | LoadBalancerClass, when specified, allows for choosing the LoadBalancer provider implementation if more than one are available or is otherwise expected to be specified |
+| `allocateLoadBalancerNodePorts` | _boolean_ | false | AllocateLoadBalancerNodePorts defines if NodePorts will be automatically allocated for services with type LoadBalancer. Default is "true". It may be set to "false" if the cluster load-balancer does not rely on NodePorts. If the caller requests specific NodePorts (by specifying a value), those requests will be respected, regardless of this field. This field may only be set for services with type LoadBalancer and will be cleared if the type is changed to any other type. |
+| `loadBalancerSourceRanges` | _string array_ | false | LoadBalancerSourceRanges defines a list of allowed IP addresses which will be configured as firewall rules on the platform providers load balancer. This is not guaranteed to be working as it happens outside of kubernetes and has to be supported and handled by the platform provider. This field may only be set for services with type LoadBalancer and will be cleared if the type is changed to any other type. |
+| `loadBalancerIP` | _string_ | false | LoadBalancerIP defines the IP Address of the underlying load balancer service. This field may be ignored if the load balancer provider does not support this feature. This field has been deprecated in Kubernetes, but it is still used for setting the IP Address in some cloud providers such as GCP. |
+| `externalTrafficPolicy` | _[ServiceExternalTrafficPolicy](#serviceexternaltrafficpolicy)_ | false | ExternalTrafficPolicy determines the externalTrafficPolicy for the Envoy Service. Valid options are Local and Cluster. Default is "Local". "Local" means traffic will only go to pods on the node receiving the traffic. "Cluster" means connections are loadbalanced to all pods in the cluster. |
+| `patch` | _[KubernetesPatchSpec](#kubernetespatchspec)_ | false | Patch defines how to perform the patch operation to the service |
+| `name` | _string_ | false | Name of the service. When unset, this defaults to an autogenerated name. |
+
+
+#### KubernetesWatchMode
+
+
+
+KubernetesWatchMode holds the configuration for which input resources to watch and reconcile.
+
+_Appears in:_
+- [EnvoyGatewayKubernetesProvider](#envoygatewaykubernetesprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[KubernetesWatchModeType](#kuberneteswatchmodetype)_ | true | Type indicates what watch mode to use. KubernetesWatchModeTypeNamespaces and KubernetesWatchModeTypeNamespaceSelector are currently supported By default, when this field is unset or empty, Envoy Gateway will watch for input namespaced resources from all namespaces. |
+| `namespaces` | _string array_ | true | Namespaces holds the list of namespaces that Envoy Gateway will watch for namespaced scoped resources such as Gateway, HTTPRoute and Service. Note that Envoy Gateway will continue to reconcile relevant cluster scoped resources such as GatewayClass that it is linked to. Precisely one of Namespaces and NamespaceSelector must be set. |
+| `namespaceSelector` | _[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#labelselector-v1-meta)_ | true | NamespaceSelector holds the label selector used to dynamically select namespaces. Envoy Gateway will watch for namespaces matching the specified label selector. Precisely one of Namespaces and NamespaceSelector must be set. |
+
+
+#### KubernetesWatchModeType
+
+_Underlying type:_ _string_
+
+KubernetesWatchModeType defines the type of KubernetesWatchMode
+
+_Appears in:_
+- [KubernetesWatchMode](#kuberneteswatchmode)
+
+
+
+#### LeaderElection
+
+
+
+LeaderElection defines the desired leader election settings.
+
+_Appears in:_
+- [EnvoyGatewayKubernetesProvider](#envoygatewaykubernetesprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `leaseDuration` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | true | LeaseDuration defines the time non-leader contenders will wait before attempting to claim leadership. It's based on the timestamp of the last acknowledged signal. The default setting is 15 seconds. |
+| `renewDeadline` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | true | RenewDeadline represents the time frame within which the current leader will attempt to renew its leadership status before relinquishing its position. The default setting is 10 seconds. |
+| `retryPeriod` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | true | RetryPeriod denotes the interval at which LeaderElector clients should perform action retries. The default setting is 2 seconds. |
+| `disable` | _boolean_ | true | Disable provides the option to turn off leader election, which is enabled by default. |
+
+
+#### LiteralCustomTag
+
+
+
+LiteralCustomTag adds hard-coded value to each span.
+
+_Appears in:_
+- [CustomTag](#customtag)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `value` | _string_ | true | Value defines the hard-coded value to add to each span. |
+
+
+#### LoadBalancer
+
+
+
+LoadBalancer defines the load balancer policy to be applied.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[LoadBalancerType](#loadbalancertype)_ | true | Type decides the type of Load Balancer policy. Valid LoadBalancerType values are "ConsistentHash", "LeastRequest", "Random", "RoundRobin". |
+| `consistentHash` | _[ConsistentHash](#consistenthash)_ | false | ConsistentHash defines the configuration when the load balancer type is set to ConsistentHash |
+| `slowStart` | _[SlowStart](#slowstart)_ | false | SlowStart defines the configuration related to the slow start load balancer policy. If set, during slow start window, traffic sent to the newly added hosts will gradually increase. Currently this is only supported for RoundRobin and LeastRequest load balancers |
+
+
+#### LoadBalancerType
+
+_Underlying type:_ _string_
+
+LoadBalancerType specifies the types of LoadBalancer.
+
+_Appears in:_
+- [LoadBalancer](#loadbalancer)
+
+| Value | Description |
+| ----- | ----------- |
+| `ConsistentHash` | ConsistentHashLoadBalancerType load balancer policy. |
+| `LeastRequest` | LeastRequestLoadBalancerType load balancer policy. |
+| `Random` | RandomLoadBalancerType load balancer policy. |
+| `RoundRobin` | RoundRobinLoadBalancerType load balancer policy. |
+
+
+#### LocalRateLimit
+
+
+
+LocalRateLimit defines local rate limit configuration.
+
+_Appears in:_
+- [RateLimitSpec](#ratelimitspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `rules` | _[RateLimitRule](#ratelimitrule) array_ | false | Rules are a list of RateLimit selectors and limits. If a request matches multiple rules, the strictest limit is applied. For example, if a request matches two rules, one with 10rps and one with 20rps, the final limit will be based on the rule with 10rps. |
+
+
+#### LogLevel
+
+_Underlying type:_ _string_
+
+LogLevel defines a log level for Envoy Gateway and EnvoyProxy system logs.
+
+_Appears in:_
+- [EnvoyGatewayLogging](#envoygatewaylogging)
+- [ProxyLogging](#proxylogging)
+
+| Value | Description |
+| ----- | ----------- |
+| `debug` | LogLevelDebug defines the "debug" logging level. |
+| `info` | LogLevelInfo defines the "Info" logging level. |
+| `warn` | LogLevelWarn defines the "Warn" logging level. |
+| `error` | LogLevelError defines the "Error" logging level. |
+
+
+#### MergeType
+
+_Underlying type:_ _string_
+
+MergeType defines the type of merge operation
+
+_Appears in:_
+- [KubernetesPatchSpec](#kubernetespatchspec)
+
+| Value | Description |
+| ----- | ----------- |
+| `StrategicMerge` | StrategicMerge indicates a strategic merge patch type |
+| `JSONMerge` | JSONMerge indicates a JSON merge patch type |
+
+
+#### MetricSinkType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [EnvoyGatewayMetricSink](#envoygatewaymetricsink)
+- [ProxyMetricSink](#proxymetricsink)
+
+| Value | Description |
+| ----- | ----------- |
+| `OpenTelemetry` | |
+
+
+#### OIDC
+
+
+
+OIDC defines the configuration for the OpenID Connect (OIDC) authentication.
+
+_Appears in:_
+- [SecurityPolicySpec](#securitypolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `provider` | _[OIDCProvider](#oidcprovider)_ | true | The OIDC Provider configuration. |
+| `clientID` | _string_ | true | The client ID to be used in the OIDC [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). |
+| `clientSecret` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the OIDC client secret to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
This is an Opaque secret. The client secret should be stored in the key "client-secret". |
+| `cookieNames` | _[OIDCCookieNames](#oidccookienames)_ | false | The optional cookie name overrides to be used for Bearer and IdToken cookies in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, uses a randomly generated suffix |
+| `cookieDomain` | _string_ | false | The optional domain to set the access and ID token cookies on. If not set, the cookies will default to the host of the request, not including the subdomains. If set, the cookies will be set on the specified domain and all subdomains. This means that requests to any subdomain will not require reauthentication after users log in to the parent domain. |
+| `scopes` | _string array_ | false | The OIDC scopes to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). The "openid" scope is always added to the list of scopes if not already specified. |
+| `resources` | _string array_ | false | The OIDC resources to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). |
+| `redirectURL` | _string_ | true | The redirect URL to be used in the OIDC [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" |
+| `logoutPath` | _string_ | true | The path to log a user out, clearing their credential cookies.
If not specified, uses a default logout path "/logout" |
+| `forwardAccessToken` | _boolean_ | false | ForwardAccessToken indicates whether the Envoy should forward the access token via the Authorization header Bearer scheme to the upstream. If not specified, defaults to false. |
+| `defaultTokenTTL` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | DefaultTokenTTL is the default lifetime of the id token and access token. Please note that Envoy will always use the expiry time from the response of the authorization server if it is provided. This field is only used when the expiry time is not provided by the authorization.
If not specified, defaults to 0. In this case, the "expires_in" field in the authorization response must be set by the authorization server, or the OAuth flow will fail. |
+| `refreshToken` | _boolean_ | false | RefreshToken indicates whether the Envoy should automatically refresh the id token and access token when they expire. When set to true, the Envoy will use the refresh token to get a new id token and access token when they expire.
If not specified, defaults to false. |
+| `defaultRefreshTokenTTL` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | DefaultRefreshTokenTTL is the default lifetime of the refresh token. This field is only used when the exp (expiration time) claim is omitted in the refresh token or the refresh token is not JWT.
If not specified, defaults to 604800s (one week). Note: this field is only applicable when the "refreshToken" field is set to true. |
+
+
+#### OIDCCookieNames
+
+
+
+OIDCCookieNames defines the names of cookies to use in the Envoy OIDC filter.
+
+_Appears in:_
+- [OIDC](#oidc)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `accessToken` | _string_ | false | The name of the cookie used to store the AccessToken in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, defaults to "AccessToken-(randomly generated uid)" |
+| `idToken` | _string_ | false | The name of the cookie used to store the IdToken in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, defaults to "IdToken-(randomly generated uid)" |
+
+
+#### OIDCProvider
+
+
+
+OIDCProvider defines the OIDC Provider configuration.
+
+_Appears in:_
+- [OIDC](#oidc)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+| `issuer` | _string_ | true | The OIDC Provider's [issuer identifier](https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery). Issuer MUST be a URI RFC 3986 [RFC3986] with a scheme component that MUST be https, a host component, and optionally, port and path components and no query or fragment components. |
+| `authorizationEndpoint` | _string_ | false | The OIDC Provider's [authorization endpoint](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint). If not provided, EG will try to discover it from the provider's [Well-Known Configuration Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). |
+| `tokenEndpoint` | _string_ | false | The OIDC Provider's [token endpoint](https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint). If not provided, EG will try to discover it from the provider's [Well-Known Configuration Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). |
+
+
+#### OpenTelemetryEnvoyProxyAccessLog
+
+
+
+OpenTelemetryEnvoyProxyAccessLog defines the OpenTelemetry access log sink.
+
+_Appears in:_
+- [ProxyAccessLogSink](#proxyaccesslogsink)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+| `host` | _string_ | false | Host define the extension service hostname. Deprecated: Use BackendRefs instead. |
+| `port` | _integer_ | false | Port defines the port the extension service is exposed on. Deprecated: Use BackendRefs instead. |
+| `resources` | _object (keys:string, values:string)_ | false | Resources is a set of labels that describe the source of a log entry, including envoy node info. It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). |
+
+
+#### Origin
+
+_Underlying type:_ _string_
+
+Origin is defined by the scheme (protocol), hostname (domain), and port of
+the URL used to access it. The hostname can be "precise" which is just the
+domain name or "wildcard" which is a domain name prefixed with a single
+wildcard label such as "*.example.com".
+In addition to that a single wildcard (with or without scheme) can be
+configured to match any origin.
+
+
+For example, the following are valid origins:
+- https://foo.example.com
+- https://*.example.com
+- http://foo.example.com:8080
+- http://*.example.com:8080
+- https://*
+
+_Appears in:_
+- [CORS](#cors)
+
+
+
+#### PassiveHealthCheck
+
+
+
+PassiveHealthCheck defines the configuration for passive health checks in the context of Envoy's Outlier Detection,
+see https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/outlier
+
+_Appears in:_
+- [HealthCheck](#healthcheck)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `splitExternalLocalOriginErrors` | _boolean_ | false | SplitExternalLocalOriginErrors enables splitting of errors between external and local origin. |
+| `interval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | Interval defines the time between passive health checks. |
+| `consecutiveLocalOriginFailures` | _integer_ | false | ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection. Parameter takes effect only when split_external_local_origin_errors is set to true. |
+| `consecutiveGatewayErrors` | _integer_ | false | ConsecutiveGatewayErrors sets the number of consecutive gateway errors triggering ejection. |
+| `consecutive5XxErrors` | _integer_ | false | Consecutive5xxErrors sets the number of consecutive 5xx errors triggering ejection. |
+| `baseEjectionTime` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | BaseEjectionTime defines the base duration for which a host will be ejected on consecutive failures. |
+| `maxEjectionPercent` | _integer_ | false | MaxEjectionPercent sets the maximum percentage of hosts in a cluster that can be ejected. |
+
+
+#### PathEscapedSlashAction
+
+_Underlying type:_ _string_
+
+PathEscapedSlashAction determines the action for requests that contain %2F, %2f, %5C, or %5c
+sequences in the URI path.
+
+_Appears in:_
+- [PathSettings](#pathsettings)
+
+| Value | Description |
+| ----- | ----------- |
+| `KeepUnchanged` | KeepUnchangedAction keeps escaped slashes as they arrive without changes |
+| `RejectRequest` | RejectRequestAction rejects client requests containing escaped slashes with a 400 status. gRPC requests will be rejected with the INTERNAL (13) error code. The "httpN.downstream_rq_failed_path_normalization" counter is incremented for each rejected request. |
+| `UnescapeAndRedirect` | UnescapeAndRedirect unescapes %2F and %5C sequences and redirects to the new path if these sequences were present. Redirect occurs after path normalization and merge slashes transformations if they were configured. gRPC requests will be rejected with the INTERNAL (13) error code. This option minimizes possibility of path confusion exploits by forcing request with unescaped slashes to traverse all parties: downstream client, intermediate proxies, Envoy and upstream server. The “httpN.downstream_rq_redirected_with_normalized_path” counter is incremented for each redirected request. |
+| `UnescapeAndForward` | UnescapeAndForward unescapes %2F and %5C sequences and forwards the request. Note: this option should not be enabled if intermediaries perform path based access control as it may lead to path confusion vulnerabilities. |
+
+
+#### PathSettings
+
+
+
+PathSettings provides settings that managing how the incoming path set by clients is handled.
+
+_Appears in:_
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `escapedSlashesAction` | _[PathEscapedSlashAction](#pathescapedslashaction)_ | false | EscapedSlashesAction determines how %2f, %2F, %5c, or %5C sequences in the path URI should be handled. The default is UnescapeAndRedirect. |
+| `disableMergeSlashes` | _boolean_ | false | DisableMergeSlashes allows disabling the default configuration of merging adjacent slashes in the path. Note that slash merging is not part of the HTTP spec and is provided for convenience. |
+
+
+#### PerRetryPolicy
+
+
+
+
+
+_Appears in:_
+- [Retry](#retry)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `timeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | Timeout is the timeout per retry attempt. |
+| `backOff` | _[BackOffPolicy](#backoffpolicy)_ | false | Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential back-off algorithm for retries. For additional details, see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries |
+
+
+#### PolicyTargetReferences
+
+
+
+
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+- [EnvoyExtensionPolicySpec](#envoyextensionpolicyspec)
+- [SecurityPolicySpec](#securitypolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to. This policy and the TargetRef MUST be in the same namespace for this Policy to have effect
Deprecated: use targetRefs/targetSelectors instead |
+| `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy is being attached to. |
+| `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels |
+
+
+#### Principal
+
+
+
+If there are multiple principal types, all principals must match for the rule to match.
+
+_Appears in:_
+- [AuthorizationRule](#authorizationrule)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `clientCIDRs` | _[CIDR](#cidr) array_ | false | ClientCIDRs are the IP CIDR ranges of the client. Valid examples are "192.168.1.0/24" or "2001:db8::/64"
If multiple CIDR ranges are specified, one of the CIDR ranges must match the client IP for the rule to match.
The client IP is inferred from the X-Forwarded-For header, a custom header, or the proxy protocol. You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in the `ClientTrafficPolicy` to configure how the client IP is detected. |
+| `jwt` | _[JWTPrincipal](#jwtprincipal)_ | false | JWT authorize the request based on the JWT claims and scopes. Note: in order to use JWT claims for authorization, you must configure the JWT authentication in the same `SecurityPolicy`. |
+
+
+#### ProcessingModeOptions
+
+
+
+ProcessingModeOptions defines if headers or body should be processed by the external service
+
+_Appears in:_
+- [ExtProcProcessingMode](#extprocprocessingmode)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `body` | _[ExtProcBodyProcessingMode](#extprocbodyprocessingmode)_ | false | Defines body processing mode |
+
+
+#### ProviderType
+
+_Underlying type:_ _string_
+
+ProviderType defines the types of providers supported by Envoy Gateway.
+
+_Appears in:_
+- [EnvoyGatewayProvider](#envoygatewayprovider)
+- [EnvoyProxyProvider](#envoyproxyprovider)
+
+| Value | Description |
+| ----- | ----------- |
+| `Kubernetes` | ProviderTypeKubernetes defines the "Kubernetes" provider. |
+| `Custom` | ProviderTypeCustom defines the "Custom" provider. |
+
+
+#### ProxyAccessLog
+
+
+
+
+
+_Appears in:_
+- [ProxyTelemetry](#proxytelemetry)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `disable` | _boolean_ | true | Disable disables access logging for managed proxies if set to true. |
+| `settings` | _[ProxyAccessLogSetting](#proxyaccesslogsetting) array_ | false | Settings defines accesslog settings for managed proxies. If unspecified, will send default format to stdout. |
+
+
+#### ProxyAccessLogFormat
+
+
+
+ProxyAccessLogFormat defines the format of accesslog.
+By default accesslogs are written to standard output.
+
+_Appears in:_
+- [ProxyAccessLogSetting](#proxyaccesslogsetting)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[ProxyAccessLogFormatType](#proxyaccesslogformattype)_ | true | Type defines the type of accesslog format. |
+| `text` | _string_ | false | Text defines the text accesslog format, following Envoy accesslog formatting, It's required when the format type is "Text". Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) may be used in the format. The [format string documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-strings) provides more information. |
+| `json` | _object (keys:string, values:string)_ | false | JSON is additional attributes that describe the specific event occurrence. Structured format for the envoy access logs. Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) can be used as values for fields within the Struct. It's required when the format type is "JSON". |
+
+
+#### ProxyAccessLogFormatType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [ProxyAccessLogFormat](#proxyaccesslogformat)
+
+| Value | Description |
+| ----- | ----------- |
+| `Text` | ProxyAccessLogFormatTypeText defines the text accesslog format. |
+| `JSON` | ProxyAccessLogFormatTypeJSON defines the JSON accesslog format. |
+
+
+#### ProxyAccessLogSetting
+
+
+
+
+
+_Appears in:_
+- [ProxyAccessLog](#proxyaccesslog)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `format` | _[ProxyAccessLogFormat](#proxyaccesslogformat)_ | false | Format defines the format of accesslog. This will be ignored if sink type is ALS. |
+| `matches` | _string array_ | true | Matches defines the match conditions for accesslog in CEL expression. An accesslog will be emitted only when one or more match conditions are evaluated to true. Invalid [CEL](https://www.envoyproxy.io/docs/envoy/latest/xds/type/v3/cel.proto.html#common-expression-language-cel-proto) expressions will be ignored. |
+| `sinks` | _[ProxyAccessLogSink](#proxyaccesslogsink) array_ | true | Sinks defines the sinks of accesslog. |
+| `type` | _[ProxyAccessLogType](#proxyaccesslogtype)_ | false | Type defines the component emitting the accesslog, such as Listener and Route. If type not defined, the setting would apply to: (1) All Routes. (2) Listeners if and only if Envoy does not find a matching route for a request. If type is defined, the accesslog settings would apply to the relevant component (as-is). |
+
+
+#### ProxyAccessLogSink
+
+
+
+ProxyAccessLogSink defines the sink of accesslog.
+
+_Appears in:_
+- [ProxyAccessLogSetting](#proxyaccesslogsetting)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[ProxyAccessLogSinkType](#proxyaccesslogsinktype)_ | true | Type defines the type of accesslog sink. |
+| `als` | _[ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)_ | false | ALS defines the gRPC Access Log Service (ALS) sink. |
+| `file` | _[FileEnvoyProxyAccessLog](#fileenvoyproxyaccesslog)_ | false | File defines the file accesslog sink. |
+| `openTelemetry` | _[OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)_ | false | OpenTelemetry defines the OpenTelemetry accesslog sink. |
+
+
+#### ProxyAccessLogSinkType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [ProxyAccessLogSink](#proxyaccesslogsink)
+
+| Value | Description |
+| ----- | ----------- |
+| `ALS` | ProxyAccessLogSinkTypeALS defines the gRPC Access Log Service (ALS) sink. The service must implement the Envoy gRPC Access Log Service streaming API: https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/accesslog/v3/als.proto |
+| `File` | ProxyAccessLogSinkTypeFile defines the file accesslog sink. |
+| `OpenTelemetry` | ProxyAccessLogSinkTypeOpenTelemetry defines the OpenTelemetry accesslog sink. When the provider is Kubernetes, EnvoyGateway always sends `k8s.namespace.name` and `k8s.pod.name` as additional attributes. |
+
+
+#### ProxyAccessLogType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [ProxyAccessLogSetting](#proxyaccesslogsetting)
+
+| Value | Description |
+| ----- | ----------- |
+| `Listener` | ProxyAccessLogTypeListener defines the accesslog for Listeners. https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-access-log |
+| `Route` | ProxyAccessLogTypeRoute defines the accesslog for HTTP, GRPC, UDP and TCP Routes. https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/udp/udp_proxy/v3/udp_proxy.proto#envoy-v3-api-field-extensions-filters-udp-udp-proxy-v3-udpproxyconfig-access-log https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto#envoy-v3-api-field-extensions-filters-network-tcp-proxy-v3-tcpproxy-access-log https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-access-log |
+
+
+#### ProxyBootstrap
+
+
+
+ProxyBootstrap defines Envoy Bootstrap configuration.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[BootstrapType](#bootstraptype)_ | false | Type is the type of the bootstrap configuration, it should be either Replace, Merge, or JSONPatch. If unspecified, it defaults to Replace. |
+| `value` | _string_ | false | Value is a YAML string of the bootstrap. |
+| `jsonPatches` | _[JSONPatchOperation](#jsonpatchoperation) array_ | true | JSONPatches is an array of JSONPatches to be applied to the default bootstrap. Patches are applied in the order in which they are defined. |
+
+
+#### ProxyLogComponent
+
+_Underlying type:_ _string_
+
+ProxyLogComponent defines a component that supports a configured logging level.
+
+_Appears in:_
+- [ProxyLogging](#proxylogging)
+
+| Value | Description |
+| ----- | ----------- |
+| `default` | LogComponentDefault defines the default logging component. See more details: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#cmdoption-l |
+| `upstream` | LogComponentUpstream defines the "upstream" logging component. |
+| `http` | LogComponentHTTP defines the "http" logging component. |
+| `connection` | LogComponentConnection defines the "connection" logging component. |
+| `admin` | LogComponentAdmin defines the "admin" logging component. |
+| `client` | LogComponentClient defines the "client" logging component. |
+| `filter` | LogComponentFilter defines the "filter" logging component. |
+| `main` | LogComponentMain defines the "main" logging component. |
+| `router` | LogComponentRouter defines the "router" logging component. |
+| `runtime` | LogComponentRuntime defines the "runtime" logging component. |
+
+
+#### ProxyLogging
+
+
+
+ProxyLogging defines logging parameters for managed proxies.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `level` | _object (keys:[ProxyLogComponent](#proxylogcomponent), values:[LogLevel](#loglevel))_ | true | Level is a map of logging level per component, where the component is the key and the log level is the value. If unspecified, defaults to "default: warn". |
+
+
+#### ProxyMetricSink
+
+
+
+ProxyMetricSink defines the sink of metrics.
+Default metrics sink is OpenTelemetry.
+
+_Appears in:_
+- [ProxyMetrics](#proxymetrics)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[MetricSinkType](#metricsinktype)_ | true | Type defines the metric sink type. EG currently only supports OpenTelemetry. |
+| `openTelemetry` | _[ProxyOpenTelemetrySink](#proxyopentelemetrysink)_ | false | OpenTelemetry defines the configuration for OpenTelemetry sink. It's required if the sink type is OpenTelemetry. |
+
+
+#### ProxyMetrics
+
+
+
+
+
+_Appears in:_
+- [ProxyTelemetry](#proxytelemetry)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `prometheus` | _[ProxyPrometheusProvider](#proxyprometheusprovider)_ | true | Prometheus defines the configuration for Admin endpoint `/stats/prometheus`. |
+| `sinks` | _[ProxyMetricSink](#proxymetricsink) array_ | true | Sinks defines the metric sinks where metrics are sent to. |
+| `matches` | _[StringMatch](#stringmatch) array_ | true | Matches defines configuration for selecting specific metrics instead of generating all metrics stats that are enabled by default. This helps reduce CPU and memory overhead in Envoy, but eliminating some stats may after critical functionality. Here are the stats that we strongly recommend not disabling: `cluster_manager.warming_clusters`, `cluster..membership_total`,`cluster..membership_healthy`, `cluster..membership_degraded`,reference https://github.com/envoyproxy/envoy/issues/9856, https://github.com/envoyproxy/envoy/issues/14610 |
+| `enableVirtualHostStats` | _boolean_ | false | EnableVirtualHostStats enables envoy stat metrics for virtual hosts. |
+| `enablePerEndpointStats` | _boolean_ | false | EnablePerEndpointStats enables per endpoint envoy stats metrics. Please use with caution. |
+| `enableRequestResponseSizesStats` | _boolean_ | false | EnableRequestResponseSizesStats enables publishing of histograms tracking header and body sizes of requests and responses. |
+
+
+#### ProxyOpenTelemetrySink
+
+
+
+ProxyOpenTelemetrySink defines the configuration for OpenTelemetry sink.
+
+_Appears in:_
+- [ProxyMetricSink](#proxymetricsink)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+| `host` | _string_ | false | Host define the service hostname. Deprecated: Use BackendRefs instead. |
+| `port` | _integer_ | false | Port defines the port the service is exposed on. Deprecated: Use BackendRefs instead. |
+
+
+#### ProxyPrometheusProvider
+
+
+
+
+
+_Appears in:_
+- [ProxyMetrics](#proxymetrics)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `disable` | _boolean_ | true | Disable the Prometheus endpoint. |
+| `compression` | _[Compression](#compression)_ | false | Configure the compression on Prometheus endpoint. Compression is useful in situations when bandwidth is scarce and large payloads can be effectively compressed at the expense of higher CPU load. |
+
+
+#### ProxyProtocol
+
+
+
+ProxyProtocol defines the configuration related to the proxy protocol
+when communicating with the backend.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `version` | _[ProxyProtocolVersion](#proxyprotocolversion)_ | true | Version of ProxyProtol Valid ProxyProtocolVersion values are "V1" "V2" |
+
+
+#### ProxyProtocolVersion
+
+_Underlying type:_ _string_
+
+ProxyProtocolVersion defines the version of the Proxy Protocol to use.
+
+_Appears in:_
+- [ProxyProtocol](#proxyprotocol)
+
+| Value | Description |
+| ----- | ----------- |
+| `V1` | ProxyProtocolVersionV1 is the PROXY protocol version 1 (human readable format). |
+| `V2` | ProxyProtocolVersionV2 is the PROXY protocol version 2 (binary format). |
+
+
+#### ProxyTelemetry
+
+
+
+
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `accessLog` | _[ProxyAccessLog](#proxyaccesslog)_ | false | AccessLogs defines accesslog parameters for managed proxies. If unspecified, will send default format to stdout. |
+| `tracing` | _[ProxyTracing](#proxytracing)_ | false | Tracing defines tracing configuration for managed proxies. If unspecified, will not send tracing data. |
+| `metrics` | _[ProxyMetrics](#proxymetrics)_ | true | Metrics defines metrics configuration for managed proxies. |
+
+
+#### ProxyTracing
+
+
+
+
+
+_Appears in:_
+- [ProxyTelemetry](#proxytelemetry)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `samplingRate` | _integer_ | false | SamplingRate controls the rate at which traffic will be selected for tracing if no prior sampling decision has been made. Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. |
+| `customTags` | _object (keys:string, values:[CustomTag](#customtag))_ | true | CustomTags defines the custom tags to add to each span. If provider is kubernetes, pod name and namespace are added by default. |
+| `provider` | _[TracingProvider](#tracingprovider)_ | true | Provider defines the tracing provider. |
+
+
+#### RateLimit
+
+
+
+RateLimit defines the configuration associated with the Rate Limit Service
+used for Global Rate Limiting.
+
+_Appears in:_
+- [EnvoyGateway](#envoygateway)
+- [EnvoyGatewaySpec](#envoygatewayspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backend` | _[RateLimitDatabaseBackend](#ratelimitdatabasebackend)_ | true | Backend holds the configuration associated with the database backend used by the rate limit service to store state associated with global ratelimiting. |
+| `timeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | Timeout specifies the timeout period for the proxy to access the ratelimit server If not set, timeout is 20ms. |
+| `failClosed` | _boolean_ | true | FailClosed is a switch used to control the flow of traffic when the response from the ratelimit server cannot be obtained. If FailClosed is false, let the traffic pass, otherwise, don't let the traffic pass and return 500. If not set, FailClosed is False. |
+| `telemetry` | _[RateLimitTelemetry](#ratelimittelemetry)_ | false | Telemetry defines telemetry configuration for RateLimit. |
+
+
+#### RateLimitDatabaseBackend
+
+
+
+RateLimitDatabaseBackend defines the configuration associated with
+the database backend used by the rate limit service.
+
+_Appears in:_
+- [RateLimit](#ratelimit)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[RateLimitDatabaseBackendType](#ratelimitdatabasebackendtype)_ | true | Type is the type of database backend to use. Supported types are: * Redis: Connects to a Redis database. |
+| `redis` | _[RateLimitRedisSettings](#ratelimitredissettings)_ | false | Redis defines the settings needed to connect to a Redis database. |
+
+
+#### RateLimitDatabaseBackendType
+
+_Underlying type:_ _string_
+
+RateLimitDatabaseBackendType specifies the types of database backend
+to be used by the rate limit service.
+
+_Appears in:_
+- [RateLimitDatabaseBackend](#ratelimitdatabasebackend)
+
+| Value | Description |
+| ----- | ----------- |
+| `Redis` | RedisBackendType uses a redis database for the rate limit service. |
+
+
+#### RateLimitMetrics
+
+
+
+
+
+_Appears in:_
+- [RateLimitTelemetry](#ratelimittelemetry)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `prometheus` | _[RateLimitMetricsPrometheusProvider](#ratelimitmetricsprometheusprovider)_ | true | Prometheus defines the configuration for prometheus endpoint. |
+
+
+#### RateLimitMetricsPrometheusProvider
+
+
+
+
+
+_Appears in:_
+- [RateLimitMetrics](#ratelimitmetrics)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `disable` | _boolean_ | true | Disable the Prometheus endpoint. |
+
+
+#### RateLimitRedisSettings
+
+
+
+RateLimitRedisSettings defines the configuration for connecting to redis database.
+
+_Appears in:_
+- [RateLimitDatabaseBackend](#ratelimitdatabasebackend)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `url` | _string_ | true | URL of the Redis Database. |
+| `tls` | _[RedisTLSSettings](#redistlssettings)_ | false | TLS defines TLS configuration for connecting to redis database. |
+
+
+#### RateLimitRule
+
+
+
+RateLimitRule defines the semantics for matching attributes
+from the incoming requests, and setting limits for them.
+
+_Appears in:_
+- [GlobalRateLimit](#globalratelimit)
+- [LocalRateLimit](#localratelimit)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `clientSelectors` | _[RateLimitSelectCondition](#ratelimitselectcondition) array_ | false | ClientSelectors holds the list of select conditions to select specific clients using attributes from the traffic flow. All individual select conditions must hold True for this rule and its limit to be applied.
If no client selectors are specified, the rule applies to all traffic of the targeted Route.
If the policy targets a Gateway, the rule applies to each Route of the Gateway. Please note that each Route has its own rate limit counters. For example, if a Gateway has two Routes, and the policy has a rule with limit 10rps, each Route will have its own 10rps limit. |
+| `limit` | _[RateLimitValue](#ratelimitvalue)_ | true | Limit holds the rate limit values. This limit is applied for traffic flows when the selectors compute to True, causing the request to be counted towards the limit. The limit is enforced and the request is ratelimited, i.e. a response with 429 HTTP status code is sent back to the client when the selected requests have reached the limit. |
+
+
+#### RateLimitSelectCondition
+
+
+
+RateLimitSelectCondition specifies the attributes within the traffic flow that can
+be used to select a subset of clients to be ratelimited.
+All the individual conditions must hold True for the overall condition to hold True.
+
+_Appears in:_
+- [RateLimitRule](#ratelimitrule)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `headers` | _[HeaderMatch](#headermatch) array_ | false | Headers is a list of request headers to match. Multiple header values are ANDed together, meaning, a request MUST match all the specified headers. At least one of headers or sourceCIDR condition must be specified. |
+| `sourceCIDR` | _[SourceMatch](#sourcematch)_ | false | SourceCIDR is the client IP Address range to match on. At least one of headers or sourceCIDR condition must be specified. |
+
+
+#### RateLimitSpec
+
+
+
+RateLimitSpec defines the desired state of RateLimitSpec.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[RateLimitType](#ratelimittype)_ | true | Type decides the scope for the RateLimits. Valid RateLimitType values are "Global" or "Local". |
+| `global` | _[GlobalRateLimit](#globalratelimit)_ | false | Global defines global rate limit configuration. |
+| `local` | _[LocalRateLimit](#localratelimit)_ | false | Local defines local rate limit configuration. |
+
+
+#### RateLimitTelemetry
+
+
+
+
+
+_Appears in:_
+- [RateLimit](#ratelimit)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `metrics` | _[RateLimitMetrics](#ratelimitmetrics)_ | true | Metrics defines metrics configuration for RateLimit. |
+| `tracing` | _[RateLimitTracing](#ratelimittracing)_ | true | Tracing defines traces configuration for RateLimit. |
+
+
+#### RateLimitTracing
+
+
+
+
+
+_Appears in:_
+- [RateLimitTelemetry](#ratelimittelemetry)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `samplingRate` | _integer_ | false | SamplingRate controls the rate at which traffic will be selected for tracing if no prior sampling decision has been made. Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. |
+| `provider` | _[RateLimitTracingProvider](#ratelimittracingprovider)_ | true | Provider defines the rateLimit tracing provider. Only OpenTelemetry is supported currently. |
+
+
+#### RateLimitTracingProvider
+
+
+
+RateLimitTracingProvider defines the tracing provider configuration of RateLimit
+
+_Appears in:_
+- [RateLimitTracing](#ratelimittracing)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[RateLimitTracingProviderType](#ratelimittracingprovidertype)_ | true | Type defines the tracing provider type. Since to RateLimit Exporter currently using OpenTelemetry, only OpenTelemetry is supported |
+| `url` | _string_ | true | URL is the endpoint of the trace collector that supports the OTLP protocol |
+
+
+#### RateLimitTracingProviderType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [RateLimitTracingProvider](#ratelimittracingprovider)
+
+
+
+#### RateLimitType
+
+_Underlying type:_ _string_
+
+RateLimitType specifies the types of RateLimiting.
+
+_Appears in:_
+- [RateLimitSpec](#ratelimitspec)
+
+| Value | Description |
+| ----- | ----------- |
+| `Global` | GlobalRateLimitType allows the rate limits to be applied across all Envoy proxy instances. |
+| `Local` | LocalRateLimitType allows the rate limits to be applied on a per Envoy proxy instance basis. |
+
+
+#### RateLimitUnit
+
+_Underlying type:_ _string_
+
+RateLimitUnit specifies the intervals for setting rate limits.
+Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+
+_Appears in:_
+- [RateLimitValue](#ratelimitvalue)
+
+| Value | Description |
+| ----- | ----------- |
+| `Second` | RateLimitUnitSecond specifies the rate limit interval to be 1 second. |
+| `Minute` | RateLimitUnitMinute specifies the rate limit interval to be 1 minute. |
+| `Hour` | RateLimitUnitHour specifies the rate limit interval to be 1 hour. |
+| `Day` | RateLimitUnitDay specifies the rate limit interval to be 1 day. |
+
+
+#### RateLimitValue
+
+
+
+RateLimitValue defines the limits for rate limiting.
+
+_Appears in:_
+- [RateLimitRule](#ratelimitrule)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `requests` | _integer_ | true | |
+| `unit` | _[RateLimitUnit](#ratelimitunit)_ | true | |
+
+
+#### RedisTLSSettings
+
+
+
+RedisTLSSettings defines the TLS configuration for connecting to redis database.
+
+_Appears in:_
+- [RateLimitRedisSettings](#ratelimitredissettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `certificateRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | false | CertificateRef defines the client certificate reference for TLS connections. Currently only a Kubernetes Secret of type TLS is supported. |
+
+
+#### RemoteJWKS
+
+
+
+RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote
+HTTP/HTTPS endpoint.
+
+_Appears in:_
+- [JWTProvider](#jwtprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `uri` | _string_ | true | URI is the HTTPS URI to fetch the JWKS. Envoy's system trust bundle is used to validate the server certificate. |
+
+
+#### ReplaceRegexMatch
+
+
+
+
+
+_Appears in:_
+- [HTTPPathModifier](#httppathmodifier)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `pattern` | _string_ | true | Pattern matches a regular expression against the value of the HTTP Path.The regex string must adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax. |
+| `substitution` | _string_ | true | Substitution is an expression that replaces the matched portion.The expression may include numbered capture groups that adhere to syntax documented in https://github.com/google/re2/wiki/Syntax. |
+
+
+#### RequestHeaderCustomTag
+
+
+
+RequestHeaderCustomTag adds value from request header to each span.
+
+_Appears in:_
+- [CustomTag](#customtag)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | true | Name defines the name of the request header which to extract the value from. |
+| `defaultValue` | _string_ | false | DefaultValue defines the default value to use if the request header is not set. |
+
+
+#### ResourceProviderType
+
+_Underlying type:_ _string_
+
+ResourceProviderType defines the types of custom resource providers supported by Envoy Gateway.
+
+_Appears in:_
+- [EnvoyGatewayResourceProvider](#envoygatewayresourceprovider)
+
+| Value | Description |
+| ----- | ----------- |
+| `File` | ResourceProviderTypeFile defines the "File" provider. |
+
+
+#### ResponseOverride
+
+
+
+ResponseOverride defines the configuration to override specific responses with a custom one.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `match` | _[CustomResponseMatch](#customresponsematch)_ | true | Match configuration. |
+| `response` | _[CustomResponse](#customresponse)_ | true | Response configuration. |
+
+
+#### ResponseValueType
+
+_Underlying type:_ _string_
+
+ResponseValueType defines the types of values for the response body supported by Envoy Gateway.
+
+_Appears in:_
+- [CustomResponseBody](#customresponsebody)
+
+| Value | Description |
+| ----- | ----------- |
+| `Inline` | ResponseValueTypeInline defines the "Inline" response body type. |
+| `ValueRef` | ResponseValueTypeValueRef defines the "ValueRef" response body type. |
+
+
+#### Retry
+
+
+
+Retry defines the retry strategy to be applied.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `numRetries` | _integer_ | false | NumRetries is the number of retries to be attempted. Defaults to 2. |
+| `retryOn` | _[RetryOn](#retryon)_ | false | RetryOn specifies the retry trigger condition.
If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503). |
+| `perRetry` | _[PerRetryPolicy](#perretrypolicy)_ | false | PerRetry is the retry policy to be applied per retry attempt. |
+
+
+#### RetryOn
+
+
+
+
+
+_Appears in:_
+- [Retry](#retry)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `triggers` | _[TriggerEnum](#triggerenum) array_ | false | Triggers specifies the retry trigger condition(Http/Grpc). |
+| `httpStatusCodes` | _[HTTPStatus](#httpstatus) array_ | false | HttpStatusCodes specifies the http status codes to be retried. The retriable-status-codes trigger must also be configured for these status codes to trigger a retry. |
+
+
+#### RoutingType
+
+_Underlying type:_ _string_
+
+RoutingType defines the type of routing of this Envoy proxy.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Value | Description |
+| ----- | ----------- |
+| `Service` | ServiceRoutingType is the RoutingType for Service Cluster IP routing. |
+| `Endpoint` | EndpointRoutingType is the RoutingType for Endpoint routing. |
+
+
+#### SecurityPolicy
+
+
+
+SecurityPolicy allows the user to configure various security settings for a
+Gateway.
+
+
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1`
+| `kind` | _string_ | |`SecurityPolicy`
+| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` | _[SecurityPolicySpec](#securitypolicyspec)_ | true | Spec defines the desired state of SecurityPolicy. |
+| `status` | _[PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus)_ | true | Status defines the current status of SecurityPolicy. |
+
+
+#### SecurityPolicySpec
+
+
+
+SecurityPolicySpec defines the desired state of SecurityPolicy.
+
+_Appears in:_
+- [SecurityPolicy](#securitypolicy)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to. This policy and the TargetRef MUST be in the same namespace for this Policy to have effect
Deprecated: use targetRefs/targetSelectors instead |
+| `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy is being attached to. |
+| `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels |
+| `cors` | _[CORS](#cors)_ | false | CORS defines the configuration for Cross-Origin Resource Sharing (CORS). |
+| `basicAuth` | _[BasicAuth](#basicauth)_ | false | BasicAuth defines the configuration for the HTTP Basic Authentication. |
+| `jwt` | _[JWT](#jwt)_ | false | JWT defines the configuration for JSON Web Token (JWT) authentication. |
+| `oidc` | _[OIDC](#oidc)_ | false | OIDC defines the configuration for the OpenID Connect (OIDC) authentication. |
+| `extAuth` | _[ExtAuth](#extauth)_ | false | ExtAuth defines the configuration for External Authorization. |
+| `authorization` | _[Authorization](#authorization)_ | false | Authorization defines the authorization configuration. |
+
+
+#### ServiceExternalTrafficPolicy
+
+_Underlying type:_ _string_
+
+ServiceExternalTrafficPolicy describes how nodes distribute service traffic they
+receive on one of the Service's "externally-facing" addresses (NodePorts, ExternalIPs,
+and LoadBalancer IPs.
+
+_Appears in:_
+- [KubernetesServiceSpec](#kubernetesservicespec)
+
+| Value | Description |
+| ----- | ----------- |
+| `Cluster` | ServiceExternalTrafficPolicyCluster routes traffic to all endpoints. |
+| `Local` | ServiceExternalTrafficPolicyLocal preserves the source IP of the traffic by routing only to endpoints on the same node as the traffic was received on (dropping the traffic if there are no local endpoints). |
+
+
+#### ServiceType
+
+_Underlying type:_ _string_
+
+ServiceType string describes ingress methods for a service
+
+_Appears in:_
+- [KubernetesServiceSpec](#kubernetesservicespec)
+
+| Value | Description |
+| ----- | ----------- |
+| `ClusterIP` | ServiceTypeClusterIP means a service will only be accessible inside the cluster, via the cluster IP. |
+| `LoadBalancer` | ServiceTypeLoadBalancer means a service will be exposed via an external load balancer (if the cloud provider supports it). |
+| `NodePort` | ServiceTypeNodePort means a service will be exposed on each Kubernetes Node at a static Port, common across all Nodes. |
+
+
+#### Session
+
+
+
+Session defines settings related to TLS session management.
+
+_Appears in:_
+- [ClientTLSSettings](#clienttlssettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `resumption` | _[SessionResumption](#sessionresumption)_ | false | Resumption determines the proxy's supported TLS session resumption option. By default, Envoy Gateway does not enable session resumption. Use sessionResumption to enable stateful and stateless session resumption. Users should consider security impacts of different resumption methods. Performance gains from resumption are diminished when Envoy proxy is deployed with more than one replica. |
+
+
+#### SessionResumption
+
+
+
+SessionResumption defines supported tls session resumption methods and their associated configuration.
+
+_Appears in:_
+- [Session](#session)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `stateless` | _[StatelessTLSSessionResumption](#statelesstlssessionresumption)_ | false | Stateless defines setting for stateless (session-ticket based) session resumption |
+| `stateful` | _[StatefulTLSSessionResumption](#statefultlssessionresumption)_ | false | Stateful defines setting for stateful (session-id based) session resumption |
+
+
+#### ShutdownConfig
+
+
+
+ShutdownConfig defines configuration for graceful envoy shutdown process.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `drainTimeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds. If unspecified, defaults to 60 seconds. |
+| `minDrainDuration` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete. If unspecified, defaults to 10 seconds. |
+
+
+#### ShutdownManager
+
+
+
+ShutdownManager defines the configuration for the shutdown manager.
+
+_Appears in:_
+- [EnvoyGatewayKubernetesProvider](#envoygatewaykubernetesprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `image` | _string_ | true | Image specifies the ShutdownManager container image to be used, instead of the default image. |
+
+
+#### SlowStart
+
+
+
+SlowStart defines the configuration related to the slow start load balancer policy.
+
+_Appears in:_
+- [LoadBalancer](#loadbalancer)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `window` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | Window defines the duration of the warm up period for newly added host. During slow start window, traffic sent to the newly added hosts will gradually increase. Currently only supports linear growth of traffic. For additional details, see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig |
+
+
+#### SourceMatch
+
+
+
+
+
+_Appears in:_
+- [RateLimitSelectCondition](#ratelimitselectcondition)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[SourceMatchType](#sourcematchtype)_ | false | |
+| `value` | _string_ | true | Value is the IP CIDR that represents the range of Source IP Addresses of the client. These could also be the intermediate addresses through which the request has flown through and is part of the `X-Forwarded-For` header. For example, `192.168.0.1/32`, `192.168.0.0/24`, `001:db8::/64`. |
+
+
+#### SourceMatchType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [SourceMatch](#sourcematch)
+
+| Value | Description |
+| ----- | ----------- |
+| `Exact` | SourceMatchExact All IP Addresses within the specified Source IP CIDR are treated as a single client selector and share the same rate limit bucket. |
+| `Distinct` | SourceMatchDistinct Each IP Address within the specified Source IP CIDR is treated as a distinct client selector and uses a separate rate limit bucket/counter. Note: This is only supported for Global Rate Limits. |
+
+
+#### StatefulTLSSessionResumption
+
+
+
+StatefulTLSSessionResumption defines the stateful (session-id based) type of TLS session resumption.
+Note: When Envoy Proxy is deployed with more than one replica, session caches are not synchronized
+between instances, possibly leading to resumption failures.
+Envoy does not re-validate client certificates upon session resumption.
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-routematch-tlscontextmatchoptions
+
+_Appears in:_
+- [SessionResumption](#sessionresumption)
+
+
+
+#### StatelessTLSSessionResumption
+
+
+
+StatelessTLSSessionResumption defines the stateless (session-ticket based) type of TLS session resumption.
+Note: When Envoy Proxy is deployed with more than one replica, session ticket encryption keys are not
+synchronized between instances, possibly leading to resumption failures.
+In-memory session ticket encryption keys are rotated every 48 hours.
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#extensions-transport-sockets-tls-v3-tlssessionticketkeys
+https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#Session-tickets
+
+_Appears in:_
+- [SessionResumption](#sessionresumption)
+
+
+
+#### StatusCodeMatch
+
+
+
+StatusCodeMatch defines the configuration for matching a status code.
+
+_Appears in:_
+- [CustomResponseMatch](#customresponsematch)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[StatusCodeValueType](#statuscodevaluetype)_ | true | Type is the type of value. Valid values are Value and Range, default is Value. |
+| `value` | _integer_ | false | Value contains the value of the status code. |
+| `range` | _[StatusCodeRange](#statuscoderange)_ | false | Range contains the range of status codes. |
+
+
+#### StatusCodeRange
+
+
+
+StatusCodeRange defines the configuration for define a range of status codes.
+
+_Appears in:_
+- [StatusCodeMatch](#statuscodematch)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `start` | _integer_ | true | Start of the range, including the start value. |
+| `end` | _integer_ | true | End of the range, including the end value. |
+
+
+#### StatusCodeValueType
+
+_Underlying type:_ _string_
+
+StatusCodeValueType defines the types of values for the status code match supported by Envoy Gateway.
+
+_Appears in:_
+- [StatusCodeMatch](#statuscodematch)
+
+| Value | Description |
+| ----- | ----------- |
+| `Value` | StatusCodeValueTypeValue defines the "Value" status code match type. |
+| `Range` | StatusCodeValueTypeRange defines the "Range" status code match type. |
+
+
+#### StringMatch
+
+
+
+StringMatch defines how to match any strings.
+This is a general purpose match condition that can be used by other EG APIs
+that need to match against a string.
+
+_Appears in:_
+- [ProxyMetrics](#proxymetrics)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[StringMatchType](#stringmatchtype)_ | false | Type specifies how to match against a string. |
+| `value` | _string_ | true | Value specifies the string value that the match must have. |
+
+
+#### StringMatchType
+
+_Underlying type:_ _string_
+
+StringMatchType specifies the semantics of how a string value should be compared.
+Valid MatchType values are "Exact", "Prefix", "Suffix", "RegularExpression".
+
+_Appears in:_
+- [StringMatch](#stringmatch)
+
+| Value | Description |
+| ----- | ----------- |
+| `Exact` | StringMatchExact :the input string must match exactly the match value. |
+| `Prefix` | StringMatchPrefix :the input string must start with the match value. |
+| `Suffix` | StringMatchSuffix :the input string must end with the match value. |
+| `RegularExpression` | StringMatchRegularExpression :The input string must match the regular expression specified in the match value. The regex string must adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax. |
+
+
+#### TCPActiveHealthChecker
+
+
+
+TCPActiveHealthChecker defines the settings of tcp health check.
+
+_Appears in:_
+- [ActiveHealthCheck](#activehealthcheck)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `send` | _[ActiveHealthCheckPayload](#activehealthcheckpayload)_ | false | Send defines the request payload. |
+| `receive` | _[ActiveHealthCheckPayload](#activehealthcheckpayload)_ | false | Receive defines the expected response payload. |
+
+
+#### TCPClientTimeout
+
+
+
+TCPClientTimeout only provides timeout configuration on the listener whose protocol is TCP or TLS.
+
+_Appears in:_
+- [ClientTimeout](#clienttimeout)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | IdleTimeout for a TCP connection. Idle time is defined as a period in which there are no bytes sent or received on either the upstream or downstream connection. Default: 1 hour. |
+
+
+#### TCPKeepalive
+
+
+
+TCPKeepalive define the TCP Keepalive configuration.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `probes` | _integer_ | false | The total number of unacknowledged probes to send before deciding the connection is dead. Defaults to 9. |
+| `idleTime` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The duration a connection needs to be idle before keep-alive probes start being sent. The duration format is Defaults to `7200s`. |
+| `interval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The duration between keep-alive probes. Defaults to `75s`. |
+
+
+#### TCPTimeout
+
+
+
+
+
+_Appears in:_
+- [Timeout](#timeout)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `connectTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The timeout for network connection establishment, including TCP and TLS handshakes. Default: 10 seconds. |
+
+
+#### TLSSettings
+
+
+
+
+
+_Appears in:_
+- [BackendTLSConfig](#backendtlsconfig)
+- [ClientTLSSettings](#clienttlssettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `minVersion` | _[TLSVersion](#tlsversion)_ | false | Min specifies the minimal TLS protocol version to allow. The default is TLS 1.2 if this is not specified. |
+| `maxVersion` | _[TLSVersion](#tlsversion)_ | false | Max specifies the maximal TLS protocol version to allow The default is TLS 1.3 if this is not specified. |
+| `ciphers` | _string array_ | false | Ciphers specifies the set of cipher suites supported when negotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3. In non-FIPS Envoy Proxy builds the default cipher list is: - [ECDHE-ECDSA-AES128-GCM-SHA256\|ECDHE-ECDSA-CHACHA20-POLY1305] - [ECDHE-RSA-AES128-GCM-SHA256\|ECDHE-RSA-CHACHA20-POLY1305] - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 In builds using BoringSSL FIPS the default cipher list is: - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 |
+| `ecdhCurves` | _string array_ | false | ECDHCurves specifies the set of supported ECDH curves. In non-FIPS Envoy Proxy builds the default curves are: - X25519 - P-256 In builds using BoringSSL FIPS the default curve is: - P-256 |
+| `signatureAlgorithms` | _string array_ | false | SignatureAlgorithms specifies which signature algorithms the listener should support. |
+| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be exposed by the listener. By default h2 and http/1.1 are enabled. Supported values are: - http/1.0 - http/1.1 - h2 |
+
+
+#### TLSVersion
+
+_Underlying type:_ _string_
+
+TLSVersion specifies the TLS version
+
+_Appears in:_
+- [BackendTLSConfig](#backendtlsconfig)
+- [ClientTLSSettings](#clienttlssettings)
+- [TLSSettings](#tlssettings)
+
+| Value | Description |
+| ----- | ----------- |
+| `Auto` | TLSAuto allows Envoy to choose the optimal TLS Version |
+| `1.0` | TLS1.0 specifies TLS version 1.0 |
+| `1.1` | TLS1.1 specifies TLS version 1.1 |
+| `1.2` | TLSv1.2 specifies TLS version 1.2 |
+| `1.3` | TLSv1.3 specifies TLS version 1.3 |
+
+
+#### TargetSelector
+
+
+
+
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+- [EnvoyExtensionPolicySpec](#envoyextensionpolicyspec)
+- [PolicyTargetReferences](#policytargetreferences)
+- [SecurityPolicySpec](#securitypolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `group` | _[Group](#group)_ | true | Group is the group that this selector targets. Defaults to gateway.networking.k8s.io |
+| `kind` | _[Kind](#kind)_ | true | Kind is the resource kind that this selector targets. |
+| `matchLabels` | _object (keys:string, values:string)_ | true | MatchLabels are the set of label selectors for identifying the targeted resource |
+
+
+#### Timeout
+
+
+
+Timeout defines configuration for timeouts related to connections.
+
+_Appears in:_
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ClusterSettings](#clustersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `tcp` | _[TCPTimeout](#tcptimeout)_ | false | Timeout settings for TCP. |
+| `http` | _[HTTPTimeout](#httptimeout)_ | false | Timeout settings for HTTP. |
+
+
+#### TracingProvider
+
+
+
+TracingProvider defines the tracing provider configuration.
+
+_Appears in:_
+- [ProxyTracing](#proxytracing)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
+| `type` | _[TracingProviderType](#tracingprovidertype)_ | true | Type defines the tracing provider type. |
+| `host` | _string_ | false | Host define the provider service hostname. Deprecated: Use BackendRefs instead. |
+| `port` | _integer_ | false | Port defines the port the provider service is exposed on. Deprecated: Use BackendRefs instead. |
+| `zipkin` | _[ZipkinTracingProvider](#zipkintracingprovider)_ | false | Zipkin defines the Zipkin tracing provider configuration |
+
+
+#### TracingProviderType
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [TracingProvider](#tracingprovider)
+
+| Value | Description |
+| ----- | ----------- |
+| `OpenTelemetry` | |
+| `OpenTelemetry` | |
+| `Zipkin` | |
+| `Datadog` | |
+
+
+#### TriggerEnum
+
+_Underlying type:_ _string_
+
+TriggerEnum specifies the conditions that trigger retries.
+
+_Appears in:_
+- [RetryOn](#retryon)
+
+| Value | Description |
+| ----- | ----------- |
+| `5xx` | The upstream server responds with any 5xx response code, or does not respond at all (disconnect/reset/read timeout). Includes connect-failure and refused-stream. |
+| `gateway-error` | The response is a gateway error (502,503 or 504). |
+| `reset` | The upstream server does not respond at all (disconnect/reset/read timeout.) |
+| `connect-failure` | Connection failure to the upstream server (connect timeout, etc.). (Included in *5xx*) |
+| `retriable-4xx` | The upstream server responds with a retriable 4xx response code. Currently, the only response code in this category is 409. |
+| `refused-stream` | The upstream server resets the stream with a REFUSED_STREAM error code. |
+| `retriable-status-codes` | The upstream server responds with any response code matching one defined in the RetriableStatusCodes. |
+| `cancelled` | The gRPC status code in the response headers is “cancelled”. |
+| `deadline-exceeded` | The gRPC status code in the response headers is “deadline-exceeded”. |
+| `internal` | The gRPC status code in the response headers is “internal”. |
+| `resource-exhausted` | The gRPC status code in the response headers is “resource-exhausted”. |
+| `unavailable` | The gRPC status code in the response headers is “unavailable”. |
+
+
+#### UnixSocket
+
+
+
+UnixSocket describes TCP/UDP unix domain socket address, corresponding to Envoy's Pipe
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-pipe
+
+_Appears in:_
+- [BackendEndpoint](#backendendpoint)
+- [ExtensionService](#extensionservice)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `path` | _string_ | true | Path defines the unix domain socket path of the backend endpoint. |
+
+
+#### Wasm
+
+
+
+Wasm defines a Wasm extension.
+
+
+Note: at the moment, Envoy Gateway does not support configuring Wasm runtime.
+v8 is used as the VM runtime for the Wasm extensions.
+
+_Appears in:_
+- [EnvoyExtensionPolicySpec](#envoyextensionpolicyspec)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `name` | _string_ | false | Name is a unique name for this Wasm extension. It is used to identify the Wasm extension if multiple extensions are handled by the same vm_id and root_id. It's also used for logging/debugging. If not specified, EG will generate a unique name for the Wasm extension. |
+| `rootID` | _string_ | true | RootID is a unique ID for a set of extensions in a VM which will share a RootContext and Contexts if applicable (e.g., an Wasm HttpFilter and an Wasm AccessLog). If left blank, all extensions with a blank root_id with the same vm_id will share Context(s).
Note: RootID must match the root_id parameter used to register the Context in the Wasm code. |
+| `code` | _[WasmCodeSource](#wasmcodesource)_ | true | Code is the Wasm code for the extension. |
+| `config` | _[JSON](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#json-v1-apiextensions-k8s-io)_ | false | Config is the configuration for the Wasm extension. This configuration will be passed as a JSON string to the Wasm extension. |
+| `failOpen` | _boolean_ | false | FailOpen is a switch used to control the behavior when a fatal error occurs during the initialization or the execution of the Wasm extension. If FailOpen is set to true, the system bypasses the Wasm extension and allows the traffic to pass through. Otherwise, if it is set to false or not set (defaulting to false), the system blocks the traffic and returns an HTTP 5xx error. |
+
+
+#### WasmCodeSource
+
+
+
+WasmCodeSource defines the source of the Wasm code.
+
+_Appears in:_
+- [Wasm](#wasm)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `type` | _[WasmCodeSourceType](#wasmcodesourcetype)_ | true | Type is the type of the source of the Wasm code. Valid WasmCodeSourceType values are "HTTP" or "Image". |
+| `http` | _[HTTPWasmCodeSource](#httpwasmcodesource)_ | false | HTTP is the HTTP URL containing the Wasm code.
Note that the HTTP server must be accessible from the Envoy proxy. |
+| `image` | _[ImageWasmCodeSource](#imagewasmcodesource)_ | false | Image is the OCI image containing the Wasm code.
Note that the image must be accessible from the Envoy Gateway. |
+| `pullPolicy` | _[ImagePullPolicy](#imagepullpolicy)_ | false | PullPolicy is the policy to use when pulling the Wasm module by either the HTTP or Image source. This field is only applicable when the SHA256 field is not set.
If not specified, the default policy is IfNotPresent except for OCI images whose tag is latest.
Note: EG does not update the Wasm module every time an Envoy proxy requests the Wasm module even if the pull policy is set to Always. It only updates the Wasm module when the EnvoyExtension resource version changes. |
+
+
+#### WasmCodeSourceType
+
+_Underlying type:_ _string_
+
+WasmCodeSourceType specifies the types of sources for the Wasm code.
+
+_Appears in:_
+- [WasmCodeSource](#wasmcodesource)
+
+| Value | Description |
+| ----- | ----------- |
+| `HTTP` | HTTPWasmCodeSourceType allows the user to specify the Wasm code in an HTTP URL. |
+| `Image` | ImageWasmCodeSourceType allows the user to specify the Wasm code in an OCI image. |
+
+
+#### WithUnderscoresAction
+
+_Underlying type:_ _string_
+
+WithUnderscoresAction configures the action to take when an HTTP header with underscores
+is encountered.
+
+_Appears in:_
+- [HeaderSettings](#headersettings)
+
+| Value | Description |
+| ----- | ----------- |
+| `Allow` | WithUnderscoresActionAllow allows headers with underscores to be passed through. |
+| `RejectRequest` | WithUnderscoresActionRejectRequest rejects the client request. HTTP/1 requests are rejected with the 400 status. HTTP/2 requests end with the stream reset. |
+| `DropHeader` | WithUnderscoresActionDropHeader drops the client header with name containing underscores. The header is dropped before the filter chain is invoked and as such filters will not see dropped headers. |
+
+
+#### XDSTranslatorHook
+
+_Underlying type:_ _string_
+
+XDSTranslatorHook defines the types of hooks that an Envoy Gateway extension may support
+for the xds-translator
+
+_Appears in:_
+- [XDSTranslatorHooks](#xdstranslatorhooks)
+
+| Value | Description |
+| ----- | ----------- |
+| `VirtualHost` | |
+| `Route` | |
+| `HTTPListener` | |
+| `Translation` | |
+
+
+#### XDSTranslatorHooks
+
+
+
+XDSTranslatorHooks contains all the pre and post hooks for the xds-translator runner.
+
+_Appears in:_
+- [ExtensionHooks](#extensionhooks)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `pre` | _[XDSTranslatorHook](#xdstranslatorhook) array_ | true | |
+| `post` | _[XDSTranslatorHook](#xdstranslatorhook) array_ | true | |
+
+
+#### XFCCCertData
+
+_Underlying type:_ _string_
+
+XFCCCertData specifies the fields in the client certificate to be forwarded in the XFCC header.
+
+_Appears in:_
+- [XForwardedClientCert](#xforwardedclientcert)
+
+| Value | Description |
+| ----- | ----------- |
+| `Subject` | XFCCCertDataSubject is the Subject field of the current client certificate. |
+| `Cert` | XFCCCertDataCert is the entire client certificate in URL encoded PEM format. |
+| `Chain` | XFCCCertDataChain is the entire client certificate chain (including the leaf certificate) in URL encoded PEM format. |
+| `DNS` | XFCCCertDataDNS is the DNS type Subject Alternative Name field of the current client certificate. |
+| `URI` | XFCCCertDataURI is the URI type Subject Alternative Name field of the current client certificate. |
+
+
+#### XFCCForwardMode
+
+_Underlying type:_ _string_
+
+XFCCForwardMode defines how XFCC header is handled by Envoy Proxy.
+
+_Appears in:_
+- [XForwardedClientCert](#xforwardedclientcert)
+
+| Value | Description |
+| ----- | ----------- |
+| `Sanitize` | XFCCForwardModeSanitize removes the XFCC header from the request. This is the default mode. |
+| `ForwardOnly` | XFCCForwardModeForwardOnly forwards the XFCC header in the request if the client connection is mTLS. |
+| `AppendForward` | XFCCForwardModeAppendForward appends the client certificate information to the request’s XFCC header and forward it if the client connection is mTLS. |
+| `SanitizeSet` | XFCCForwardModeSanitizeSet resets the XFCC header with the client certificate information and forward it if the client connection is mTLS. The existing certificate information in the XFCC header is removed. |
+| `AlwaysForwardOnly` | XFCCForwardModeAlwaysForwardOnly always forwards the XFCC header in the request, regardless of whether the client connection is mTLS. |
+
+
+#### XForwardedClientCert
+
+
+
+XForwardedClientCert configures how Envoy Proxy handle the x-forwarded-client-cert (XFCC) HTTP header.
+
+_Appears in:_
+- [HeaderSettings](#headersettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `mode` | _[XFCCForwardMode](#xfccforwardmode)_ | false | Mode defines how XFCC header is handled by Envoy Proxy. If not set, the default mode is `Sanitize`. |
+| `certDetailsToAdd` | _[XFCCCertData](#xfcccertdata) array_ | false | CertDetailsToAdd specifies the fields in the client certificate to be forwarded in the XFCC header.
Hash(the SHA 256 digest of the current client certificate) and By(the Subject Alternative Name) are always included if the client certificate is forwarded.
This field is only applicable when the mode is set to `AppendForward` or `SanitizeSet` and the client connection is mTLS. |
+
+
+#### XForwardedForSettings
+
+
+
+XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address.
+Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
+for more details.
+
+_Appears in:_
+- [ClientIPDetectionSettings](#clientipdetectionsettings)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `numTrustedHops` | _integer_ | false | NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP headers to trust when determining the origin client's IP address. Only one of NumTrustedHops and TrustedCIDRs must be set. |
+
+
+#### ZipkinTracingProvider
+
+
+
+ZipkinTracingProvider defines the Zipkin tracing provider configuration.
+
+_Appears in:_
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `enable128BitTraceId` | _boolean_ | false | Enable128BitTraceID determines whether a 128bit trace id will be used when creating a new trace instance. If set to false, a 64bit trace id will be used. |
+| `disableSharedSpanContext` | _boolean_ | false | DisableSharedSpanContext determines whether the default Envoy behaviour of client and server spans sharing the same span context should be disabled. |
+
+
diff --git a/site/content/en/v1.2/boilerplates/index.md b/site/content/en/v1.2/boilerplates/index.md
new file mode 100644
index 00000000000..dda80adbcbf
--- /dev/null
+++ b/site/content/en/v1.2/boilerplates/index.md
@@ -0,0 +1,5 @@
+---
+headless: true
+---
+
+This file tells Hugo that the files in this directory tree shouldn't be rendered as normal pages on the site.
diff --git a/site/content/en/v1.2/boilerplates/o11y_prerequisites.md b/site/content/en/v1.2/boilerplates/o11y_prerequisites.md
new file mode 100644
index 00000000000..2d33128946f
--- /dev/null
+++ b/site/content/en/v1.2/boilerplates/o11y_prerequisites.md
@@ -0,0 +1,14 @@
+---
+---
+
+Follow the steps from the [Quickstart](../tasks/quickstart) to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+Envoy Gateway provides an add-ons Helm Chart, which includes all the needing components for observability.
+By default, the [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) is disabled.
+
+Install the add-ons Helm Chart:
+
+```shell
+helm install eg-addons oci://docker.io/envoyproxy/gateway-addons-helm --version {{< helm-version >}} --set opentelemetry-collector.enabled=true -n monitoring --create-namespace
+```
diff --git a/site/content/en/v1.2/boilerplates/prerequisites.md b/site/content/en/v1.2/boilerplates/prerequisites.md
new file mode 100644
index 00000000000..064238e4d13
--- /dev/null
+++ b/site/content/en/v1.2/boilerplates/prerequisites.md
@@ -0,0 +1,24 @@
+---
+---
+
+Follow the steps from the [Quickstart](../tasks/quickstart) task to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+Verify the Gateway status:
+
+{{< tabpane text=true >}}
+{{% tab header="kubectl" %}}
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+{{% /tab %}}
+{{% tab header="egctl (experimental)" %}}
+
+```shell
+egctl x status gateway -v
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
diff --git a/site/content/en/v1.2/boilerplates/rollout-envoy-gateway.md b/site/content/en/v1.2/boilerplates/rollout-envoy-gateway.md
new file mode 100644
index 00000000000..9072526868c
--- /dev/null
+++ b/site/content/en/v1.2/boilerplates/rollout-envoy-gateway.md
@@ -0,0 +1,10 @@
+---
+---
+
+> After updating the `ConfigMap`, you will need to wait the configuration kicks in.
+> You can **force** the configuration to be reloaded by restarting the `envoy-gateway` deployment.
+>
+> ```shell
+> kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
+> ```
+>
\ No newline at end of file
diff --git a/site/content/en/v1.2/concepts/_index.md b/site/content/en/v1.2/concepts/_index.md
new file mode 100644
index 00000000000..4d568bd4491
--- /dev/null
+++ b/site/content/en/v1.2/concepts/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Concepts"
+weight: 1
+description: Learn about key concepts when working with Envoy Gateway
+---
diff --git a/site/content/en/v1.2/concepts/concepts_overview.md b/site/content/en/v1.2/concepts/concepts_overview.md
new file mode 100644
index 00000000000..6f37f87f283
--- /dev/null
+++ b/site/content/en/v1.2/concepts/concepts_overview.md
@@ -0,0 +1,56 @@
++++
+title = "Envoy Gateway Resources"
++++
+
+There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
+
+## Overview
+
+![](/img/envoy-gateway-resources-overview.png)
+
+There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
+
+### Kubernetes Gateway API Resources
+- **GatewayClass:** Defines a class of Gateways with common configuration.
+- **Gateway:** Specifies how traffic can enter the cluster.
+- **Routes:** **HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute:** Define routing rules for different types of traffic.
+
+### Envoy Gateway (EG) API Resources
+- **EnvoyProxy:** Represents the deployment and configuration of the Envoy proxy within a Kubernetes cluster, managing its lifecycle and settings.
+- **EnvoyPatchPolicy, ClientTrafficPolicy, SecurityPolicy, BackendTrafficPolicy, EnvoyExtensionPolicy, BackendTLSPolicy:** Additional policies and configurations specific to Envoy Gateway.
+- **Backend:** A resource that makes routing to cluster-external backends easier and makes access to external processes via Unix Domain Sockets possible.
+
+| Resource | API | Required | Purpose | References | Description |
+| ----------------------------------------------------------------------- | ----------- | -------- | ------------------ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [GatewayClass][1] | Gateway API | Yes | Gateway Config | Core | Defines a class of Gateways with common configuration. |
+| [Gateway][2] | Gateway API | Yes | Gateway Config | GatewayClass | Specifies how traffic can enter the cluster. |
+| [HTTPRoute][3] [GRPCRoute][4] [TLSRoute][5] [TCPRoute][6] [UDPRoute][7] | Gateway API | Yes | Routing | Gateway | Define routing rules for different types of traffic. **Note:**_For simplicity these resources are referenced collectively as Route in the References column_ |
+| [Backend][8] | EG API | No | Routing | N/A | Used for routing to cluster-external backends using FQDN or IP. Can also be used when you want to extend Envoy with external processes accessed via Unix Domain Sockets. |
+| [ClientTrafficPolicy][9] | EG API | No | Traffic Handling | Gateway | Specifies policies for handling client traffic, including rate limiting, retries, and other client-specific configurations. |
+| [BackendTrafficPolicy][10] | EG API | No | Traffic Handling | Gateway, Route | Specifies policies for traffic directed towards backend services, including load balancing, health checks, and failover strategies. **Note:**_Most specific configuration wins_ |
+| [SecurityPolicy][11] | EG API | No | Security | Gateway, Route | Defines security-related policies such as authentication, authorization, and encryption settings for traffic handled by Envoy Gateway. **Note:**_Most specific configuration wins_ |
+| [BackendTLSPolicy][12] | Gateway API | No | Security | Service | Defines TLS settings for backend connections, including certificate management, TLS version settings, and other security configurations. This policy is applied to Kubernetes Services. |
+| [EnvoyProxy][13] | EG API | No | Customize & Extend | GatewayClass, Gateway | The EnvoyProxy resource represents the deployment and configuration of the Envoy proxy itself within a Kubernetes cluster, managing its lifecycle and settings. **Note:**_Most specific configuration wins_ |
+| [EnvoyPatchPolicy][14] | EG API | No | Customize & Extend | GatewayClass, Gateway | This policy defines custom patches to be applied to Envoy Gateway resources, allowing users to tailor the configuration to their specific needs. **Note:**_Most specific configuration wins_ |
+| [EnvoyExtensionPolicy][15] | EG API | No | Customize & Extend | Gateway, Route, Backend| Allows for the configuration of Envoy proxy extensions, enabling custom behavior and functionality. **Note:**_Most specific configuration wins_ |
+| [HTTPRouteFilter][16] | EG API | No | Customize & Extend | HTTPRoute | Allows for the additional request/response processing. |
+
+
+
+
+[1]: https://gateway-api.sigs.k8s.io/api-types/gatewayclass/
+[2]: https://gateway-api.sigs.k8s.io/api-types/gateway/
+[3]: https://gateway-api.sigs.k8s.io/api-types/httproute/
+[4]: https://gateway-api.sigs.k8s.io/api-types/grpcroute/
+[5]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute
+[6]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute
+[7]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.UDPRoute
+[8]: ../tasks/traffic/backend
+[9]: ../api/extension_types#clienttrafficpolicy
+[10]: ../api/extension_types#backendtrafficpolicy
+[11]: ../api/extension_types#securitypolicy
+[12]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
+[13]: ../api/extension_types#envoyproxy
+[14]: ../api/extension_types#envoypatchpolicy
+[15]: ../api/extension_types#envoyextensionpolicy
+[16]: ../api/extension_types#httproutefilter
diff --git a/site/content/en/v1.2/install/_index.md b/site/content/en/v1.2/install/_index.md
new file mode 100644
index 00000000000..b4c6f79c6fd
--- /dev/null
+++ b/site/content/en/v1.2/install/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Installation"
+description: This section includes installation related contents of Envoy Gateway.
+weight: 70
+---
diff --git a/site/content/en/v1.2/install/custom-cert.md b/site/content/en/v1.2/install/custom-cert.md
new file mode 100644
index 00000000000..dd059c03520
--- /dev/null
+++ b/site/content/en/v1.2/install/custom-cert.md
@@ -0,0 +1,146 @@
+---
+title: Control Plane Authentication using custom certs
+weight: -70
+---
+
+Envoy Gateway establishes a secure TLS connection for control plane communication between Envoy Gateway pods and the Envoy Proxy fleet. The TLS Certificates used here are self signed and generated using a job that runs before envoy gateway is created, and these certs and mounted on to the envoy gateway and envoy proxy pods.
+
+This task will walk you through configuring custom certs for control plane auth.
+
+## Before you begin
+
+We use Cert-Manager to manage the certificates. You can install it by following the [official guide](https://cert-manager.io/docs/installation/kubernetes/).
+
+## Configure custom certs for control plane
+
+1. First you need to set up the CA issuer, in this task, we use the `selfsigned-issuer` as an example.
+
+ *You should not use the self-signed issuer in production, you should use a real CA issuer.*
+
+ ```shell
+ cat <
+
+## Maintainers
+
+| Name | Email | Url |
+| ---- | ------ | --- |
+| envoy-gateway-steering-committee | | |
+| envoy-gateway-maintainers | | |
+
+## Source Code
+
+*
+
+## Requirements
+
+| Repository | Name | Version |
+|------------|------|---------|
+| https://fluent.github.io/helm-charts | fluent-bit | 0.30.4 |
+| https://grafana.github.io/helm-charts | alloy | 0.9.2 |
+| https://grafana.github.io/helm-charts | grafana | 8.0.0 |
+| https://grafana.github.io/helm-charts | loki | 4.8.0 |
+| https://grafana.github.io/helm-charts | tempo | 1.3.1 |
+| https://open-telemetry.github.io/opentelemetry-helm-charts | opentelemetry-collector | 0.108.0 |
+| https://prometheus-community.github.io/helm-charts | prometheus | 25.21.0 |
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| alloy.alloy.configMap.content | string | `"// Write your Alloy config here:\nlogging {\n level = \"info\"\n format = \"logfmt\"\n}\nloki.write \"alloy\" {\n endpoint {\n url = \"http://loki.monitoring.svc:3100/loki/api/v1/push\"\n }\n}\n// discovery.kubernetes allows you to find scrape targets from Kubernetes resources.\n// It watches cluster state and ensures targets are continually synced with what is currently running in your cluster.\ndiscovery.kubernetes \"pod\" {\n role = \"pod\"\n}\n\n// discovery.relabel rewrites the label set of the input targets by applying one or more relabeling rules.\n// If no rules are defined, then the input targets are exported as-is.\ndiscovery.relabel \"pod_logs\" {\n targets = discovery.kubernetes.pod.targets\n\n // Label creation - \"namespace\" field from \"__meta_kubernetes_namespace\"\n rule {\n source_labels = [\"__meta_kubernetes_namespace\"]\n action = \"replace\"\n target_label = \"namespace\"\n }\n\n // Label creation - \"pod\" field from \"__meta_kubernetes_pod_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_name\"]\n action = \"replace\"\n target_label = \"pod\"\n }\n\n // Label creation - \"container\" field from \"__meta_kubernetes_pod_container_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"container\"\n }\n\n // Label creation - \"app\" field from \"__meta_kubernetes_pod_label_app_kubernetes_io_name\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_label_app_kubernetes_io_name\"]\n action = \"replace\"\n target_label = \"app\"\n }\n\n // Label creation - \"job\" field from \"__meta_kubernetes_namespace\" and \"__meta_kubernetes_pod_container_name\"\n // Concatenate values __meta_kubernetes_namespace/__meta_kubernetes_pod_container_name\n rule {\n source_labels = [\"__meta_kubernetes_namespace\", \"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"job\"\n separator = \"/\"\n replacement = \"$1\"\n }\n\n // Label creation - \"container\" field from \"__meta_kubernetes_pod_uid\" and \"__meta_kubernetes_pod_container_name\"\n // Concatenate values __meta_kubernetes_pod_uid/__meta_kubernetes_pod_container_name.log\n rule {\n source_labels = [\"__meta_kubernetes_pod_uid\", \"__meta_kubernetes_pod_container_name\"]\n action = \"replace\"\n target_label = \"__path__\"\n separator = \"/\"\n replacement = \"/var/log/pods/*$1/*.log\"\n }\n\n // Label creation - \"container_runtime\" field from \"__meta_kubernetes_pod_container_id\"\n rule {\n source_labels = [\"__meta_kubernetes_pod_container_id\"]\n action = \"replace\"\n target_label = \"container_runtime\"\n regex = \"^(\\\\S+):\\\\/\\\\/.+$\"\n replacement = \"$1\"\n }\n}\n\n// loki.source.kubernetes tails logs from Kubernetes containers using the Kubernetes API.\nloki.source.kubernetes \"pod_logs\" {\n targets = discovery.relabel.pod_logs.output\n forward_to = [loki.process.pod_logs.receiver]\n}\n// loki.process receives log entries from other Loki components, applies one or more processing stages,\n// and forwards the results to the list of receivers in the component’s arguments.\nloki.process \"pod_logs\" {\n stage.static_labels {\n values = {\n cluster = \"envoy-gateway\",\n }\n }\n\n forward_to = [loki.write.alloy.receiver]\n}"` | |
+| alloy.enabled | bool | `false` | |
+| alloy.fullnameOverride | string | `"alloy"` | |
+| fluent-bit.config.filters | string | `"[FILTER]\n Name kubernetes\n Match kube.*\n Merge_Log On\n Keep_Log Off\n K8S-Logging.Parser On\n K8S-Logging.Exclude On\n\n[FILTER]\n Name grep\n Match kube.*\n Regex $kubernetes['container_name'] ^envoy$\n\n[FILTER]\n Name parser\n Match kube.*\n Key_Name log\n Parser envoy\n Reserve_Data True\n"` | |
+| fluent-bit.config.inputs | string | `"[INPUT]\n Name tail\n Path /var/log/containers/*.log\n multiline.parser docker, cri\n Tag kube.*\n Mem_Buf_Limit 5MB\n Skip_Long_Lines On\n"` | |
+| fluent-bit.config.outputs | string | `"[OUTPUT]\n Name loki\n Match kube.*\n Host loki.monitoring.svc.cluster.local\n Port 3100\n Labels job=fluentbit, app=$kubernetes['labels']['app'], k8s_namespace_name=$kubernetes['namespace_name'], k8s_pod_name=$kubernetes['pod_name'], k8s_container_name=$kubernetes['container_name']\n"` | |
+| fluent-bit.config.service | string | `"[SERVICE]\n Daemon Off\n Flush {{ .Values.flush }}\n Log_Level {{ .Values.logLevel }}\n Parsers_File parsers.conf\n Parsers_File custom_parsers.conf\n HTTP_Server On\n HTTP_Listen 0.0.0.0\n HTTP_Port {{ .Values.metricsPort }}\n Health_Check On\n"` | |
+| fluent-bit.enabled | bool | `true` | |
+| fluent-bit.fullnameOverride | string | `"fluent-bit"` | |
+| fluent-bit.image.repository | string | `"fluent/fluent-bit"` | |
+| fluent-bit.podAnnotations."fluentbit.io/exclude" | string | `"true"` | |
+| fluent-bit.podAnnotations."prometheus.io/path" | string | `"/api/v1/metrics/prometheus"` | |
+| fluent-bit.podAnnotations."prometheus.io/port" | string | `"2020"` | |
+| fluent-bit.podAnnotations."prometheus.io/scrape" | string | `"true"` | |
+| fluent-bit.testFramework.enabled | bool | `false` | |
+| grafana.adminPassword | string | `"admin"` | |
+| grafana.dashboardProviders."dashboardproviders.yaml".apiVersion | int | `1` | |
+| grafana.dashboardProviders."dashboardproviders.yaml".providers[0].disableDeletion | bool | `false` | |
+| grafana.dashboardProviders."dashboardproviders.yaml".providers[0].editable | bool | `true` | |
+| grafana.dashboardProviders."dashboardproviders.yaml".providers[0].folder | string | `"envoy-gateway"` | |
+| grafana.dashboardProviders."dashboardproviders.yaml".providers[0].name | string | `"envoy-gateway"` | |
+| grafana.dashboardProviders."dashboardproviders.yaml".providers[0].options.path | string | `"/var/lib/grafana/dashboards/envoy-gateway"` | |
+| grafana.dashboardProviders."dashboardproviders.yaml".providers[0].orgId | int | `1` | |
+| grafana.dashboardProviders."dashboardproviders.yaml".providers[0].type | string | `"file"` | |
+| grafana.dashboardsConfigMaps.envoy-gateway | string | `"grafana-dashboards"` | |
+| grafana.datasources."datasources.yaml".apiVersion | int | `1` | |
+| grafana.datasources."datasources.yaml".datasources[0].name | string | `"Prometheus"` | |
+| grafana.datasources."datasources.yaml".datasources[0].type | string | `"prometheus"` | |
+| grafana.datasources."datasources.yaml".datasources[0].url | string | `"http://prometheus"` | |
+| grafana.enabled | bool | `true` | |
+| grafana.fullnameOverride | string | `"grafana"` | |
+| grafana.service.type | string | `"LoadBalancer"` | |
+| grafana.testFramework.enabled | bool | `false` | |
+| loki.backend.replicas | int | `0` | |
+| loki.deploymentMode | string | `"SingleBinary"` | |
+| loki.enabled | bool | `true` | |
+| loki.fullnameOverride | string | `"loki"` | |
+| loki.gateway.enabled | bool | `false` | |
+| loki.loki.auth_enabled | bool | `false` | |
+| loki.loki.commonConfig.replication_factor | int | `1` | |
+| loki.loki.compactorAddress | string | `"loki"` | |
+| loki.loki.memberlist | string | `"loki-memberlist"` | |
+| loki.loki.rulerConfig.storage.type | string | `"local"` | |
+| loki.loki.storage.type | string | `"filesystem"` | |
+| loki.monitoring.lokiCanary.enabled | bool | `false` | |
+| loki.monitoring.selfMonitoring.enabled | bool | `false` | |
+| loki.monitoring.selfMonitoring.grafanaAgent.installOperator | bool | `false` | |
+| loki.read.replicas | int | `0` | |
+| loki.singleBinary.replicas | int | `1` | |
+| loki.test.enabled | bool | `false` | |
+| loki.write.replicas | int | `0` | |
+| opentelemetry-collector.config.exporters.debug.verbosity | string | `"detailed"` | |
+| opentelemetry-collector.config.exporters.loki.endpoint | string | `"http://loki.monitoring.svc:3100/loki/api/v1/push"` | |
+| opentelemetry-collector.config.exporters.otlp.endpoint | string | `"tempo.monitoring.svc:4317"` | |
+| opentelemetry-collector.config.exporters.otlp.tls.insecure | bool | `true` | |
+| opentelemetry-collector.config.exporters.prometheus.endpoint | string | `"[${env:MY_POD_IP}]:19001"` | |
+| opentelemetry-collector.config.extensions.health_check.endpoint | string | `"[${env:MY_POD_IP}]:13133"` | |
+| opentelemetry-collector.config.processors.attributes.actions[0].action | string | `"insert"` | |
+| opentelemetry-collector.config.processors.attributes.actions[0].key | string | `"loki.attribute.labels"` | |
+| opentelemetry-collector.config.processors.attributes.actions[0].value | string | `"k8s.pod.name, k8s.namespace.name"` | |
+| opentelemetry-collector.config.receivers.datadog.endpoint | string | `"[${env:MY_POD_IP}]:8126"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.grpc.endpoint | string | `"[${env:MY_POD_IP}]:14250"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.thrift_compact.endpoint | string | `"[${env:MY_POD_IP}]:6831"` | |
+| opentelemetry-collector.config.receivers.jaeger.protocols.thrift_http.endpoint | string | `"[${env:MY_POD_IP}]:14268"` | |
+| opentelemetry-collector.config.receivers.otlp.protocols.grpc.endpoint | string | `"[${env:MY_POD_IP}]:4317"` | |
+| opentelemetry-collector.config.receivers.otlp.protocols.http.endpoint | string | `"[${env:MY_POD_IP}]:4318"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].job_name | string | `"opentelemetry-collector"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].scrape_interval | string | `"10s"` | |
+| opentelemetry-collector.config.receivers.prometheus.config.scrape_configs[0].static_configs[0].targets[0] | string | `"[${env:MY_POD_IP}]:8888"` | |
+| opentelemetry-collector.config.receivers.zipkin.endpoint | string | `"[${env:MY_POD_IP}]:9411"` | |
+| opentelemetry-collector.config.service.extensions[0] | string | `"health_check"` | |
+| opentelemetry-collector.config.service.pipelines.logs.exporters[0] | string | `"loki"` | |
+| opentelemetry-collector.config.service.pipelines.logs.processors[0] | string | `"attributes"` | |
+| opentelemetry-collector.config.service.pipelines.logs.receivers[0] | string | `"otlp"` | |
+| opentelemetry-collector.config.service.pipelines.metrics.exporters[0] | string | `"prometheus"` | |
+| opentelemetry-collector.config.service.pipelines.metrics.receivers[0] | string | `"datadog"` | |
+| opentelemetry-collector.config.service.pipelines.metrics.receivers[1] | string | `"otlp"` | |
+| opentelemetry-collector.config.service.pipelines.traces.exporters[0] | string | `"otlp"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[0] | string | `"datadog"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[1] | string | `"otlp"` | |
+| opentelemetry-collector.config.service.pipelines.traces.receivers[2] | string | `"zipkin"` | |
+| opentelemetry-collector.config.service.telemetry.metrics.address | string | `"[${env:MY_POD_IP}]:8888"` | |
+| opentelemetry-collector.enabled | bool | `false` | |
+| opentelemetry-collector.fullnameOverride | string | `"otel-collector"` | |
+| opentelemetry-collector.image.repository | string | `"otel/opentelemetry-collector-contrib"` | |
+| opentelemetry-collector.mode | string | `"deployment"` | |
+| prometheus.alertmanager.enabled | bool | `false` | |
+| prometheus.enabled | bool | `true` | |
+| prometheus.kube-state-metrics.enabled | bool | `false` | |
+| prometheus.prometheus-node-exporter.enabled | bool | `false` | |
+| prometheus.prometheus-pushgateway.enabled | bool | `false` | |
+| prometheus.server.fullnameOverride | string | `"prometheus"` | |
+| prometheus.server.global.scrape_interval | string | `"15s"` | |
+| prometheus.server.image.repository | string | `"prom/prometheus"` | |
+| prometheus.server.persistentVolume.enabled | bool | `false` | |
+| prometheus.server.readinessProbeInitialDelay | int | `0` | |
+| prometheus.server.securityContext | object | `{}` | |
+| prometheus.server.service.type | string | `"LoadBalancer"` | |
+| tempo.enabled | bool | `true` | |
+| tempo.fullnameOverride | string | `"tempo"` | |
+| tempo.service.type | string | `"LoadBalancer"` | |
+
diff --git a/site/content/en/v1.2/install/gateway-helm-api.md b/site/content/en/v1.2/install/gateway-helm-api.md
new file mode 100644
index 00000000000..bb817b992dc
--- /dev/null
+++ b/site/content/en/v1.2/install/gateway-helm-api.md
@@ -0,0 +1,75 @@
++++
+title = "Gateway Helm Chart"
++++
+
+![Version: v0.0.0-latest](https://img.shields.io/badge/Version-v0.0.0--latest-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: latest](https://img.shields.io/badge/AppVersion-latest-informational?style=flat-square)
+
+The Helm chart for Envoy Gateway
+
+**Homepage:**
+
+## Maintainers
+
+| Name | Email | Url |
+| ---- | ------ | --- |
+| envoy-gateway-steering-committee | | |
+| envoy-gateway-maintainers | | |
+
+## Source Code
+
+*
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| certgen | object | `{"job":{"affinity":{},"annotations":{},"nodeSelector":{},"resources":{},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsGroup":65534,"runAsNonRoot":true,"runAsUser":65534,"seccompProfile":{"type":"RuntimeDefault"}},"tolerations":[],"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
+| config.envoyGateway.gateway.controllerName | string | `"gateway.envoyproxy.io/gatewayclass-controller"` | |
+| config.envoyGateway.logging.level.default | string | `"info"` | |
+| config.envoyGateway.provider.type | string | `"Kubernetes"` | |
+| createNamespace | bool | `false` | |
+| deployment.envoyGateway.image.repository | string | `""` | |
+| deployment.envoyGateway.image.tag | string | `""` | |
+| deployment.envoyGateway.imagePullPolicy | string | `""` | |
+| deployment.envoyGateway.imagePullSecrets | list | `[]` | |
+| deployment.envoyGateway.resources.limits.memory | string | `"1024Mi"` | |
+| deployment.envoyGateway.resources.requests.cpu | string | `"100m"` | |
+| deployment.envoyGateway.resources.requests.memory | string | `"256Mi"` | |
+| deployment.envoyGateway.securityContext.allowPrivilegeEscalation | bool | `false` | |
+| deployment.envoyGateway.securityContext.capabilities.drop[0] | string | `"ALL"` | |
+| deployment.envoyGateway.securityContext.privileged | bool | `false` | |
+| deployment.envoyGateway.securityContext.runAsGroup | int | `65532` | |
+| deployment.envoyGateway.securityContext.runAsNonRoot | bool | `true` | |
+| deployment.envoyGateway.securityContext.runAsUser | int | `65532` | |
+| deployment.envoyGateway.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | |
+| deployment.pod.affinity | object | `{}` | |
+| deployment.pod.annotations."prometheus.io/port" | string | `"19001"` | |
+| deployment.pod.annotations."prometheus.io/scrape" | string | `"true"` | |
+| deployment.pod.labels | object | `{}` | |
+| deployment.pod.nodeSelector | object | `{}` | |
+| deployment.pod.tolerations | list | `[]` | |
+| deployment.pod.topologySpreadConstraints | list | `[]` | |
+| deployment.ports[0].name | string | `"grpc"` | |
+| deployment.ports[0].port | int | `18000` | |
+| deployment.ports[0].targetPort | int | `18000` | |
+| deployment.ports[1].name | string | `"ratelimit"` | |
+| deployment.ports[1].port | int | `18001` | |
+| deployment.ports[1].targetPort | int | `18001` | |
+| deployment.ports[2].name | string | `"wasm"` | |
+| deployment.ports[2].port | int | `18002` | |
+| deployment.ports[2].targetPort | int | `18002` | |
+| deployment.ports[3].name | string | `"metrics"` | |
+| deployment.ports[3].port | int | `19001` | |
+| deployment.ports[3].targetPort | int | `19001` | |
+| deployment.priorityClassName | string | `nil` | |
+| deployment.replicas | int | `1` | |
+| global.images.envoyGateway.image | string | `nil` | |
+| global.images.envoyGateway.pullPolicy | string | `nil` | |
+| global.images.envoyGateway.pullSecrets | list | `[]` | |
+| global.images.ratelimit.image | string | `"docker.io/envoyproxy/ratelimit:master"` | |
+| global.images.ratelimit.pullPolicy | string | `"IfNotPresent"` | |
+| global.images.ratelimit.pullSecrets | list | `[]` | |
+| kubernetesClusterDomain | string | `"cluster.local"` | |
+| podDisruptionBudget.minAvailable | int | `0` | |
+| service.annotations | object | `{}` | |
+
diff --git a/site/content/en/v1.2/install/install-egctl.md b/site/content/en/v1.2/install/install-egctl.md
new file mode 100644
index 00000000000..cbd82385740
--- /dev/null
+++ b/site/content/en/v1.2/install/install-egctl.md
@@ -0,0 +1,72 @@
+---
+title: "Install egctl"
+weight: -80
+---
+
+{{% alert title="What is egctl?" color="primary" %}}
+
+`egctl` is a command line tool to provide additional functionality for Envoy Gateway users.
+
+{{% /alert %}}
+
+
+This task shows how to install the egctl CLI. egctl can be installed either from source, or from pre-built binary releases.
+
+### From The Envoy Gateway Project
+
+The Envoy Gateway project provides two ways to fetch and install egctl. These are the official methods to get egctl releases. Installation through those methods can be found below the official methods.
+
+{{< tabpane text=true >}}
+{{% tab header="From the Binary Releases" %}}
+
+Every [release](https://github.com/envoyproxy/gateway/releases) of egctl provides binary releases for a variety of OSes. These binary versions can be manually downloaded and installed.
+
+1. Download your [desired version](https://github.com/envoyproxy/gateway/releases)
+2. Unpack it (tar -zxvf egctl_latest_linux_amd64.tar.gz)
+3. Find the egctl binary in the unpacked directory, and move it to its desired destination (mv bin/linux/amd64/egctl /usr/local/bin/egctl)
+
+From there, you should be able to run: `egctl help`.
+
+{{% /tab %}}
+{{% tab header="From Script" %}}
+
+`egctl` now has an installer script that will automatically grab the latest release version of egctl and install it locally.
+
+You can fetch that script, and then execute it locally. It's well documented so that you can read through it and understand what it is doing before you run it.
+
+```shell
+curl -fsSL -o get-egctl.sh https://gateway.envoyproxy.io/get-egctl.sh
+
+chmod +x get-egctl.sh
+
+# get help info of the
+bash get-egctl.sh --help
+
+# install the latest development version of egctl
+bash VERSION=latest get-egctl.sh
+```
+
+Yes, you can just use the below command if you want to live on the edge.
+
+```shell
+curl -fsSL https://gateway.envoyproxy.io/get-egctl.sh | VERSION=latest bash
+```
+
+{{% /tab %}}
+
+{{% tab header="From Homebrew" %}}
+
+You can also install egctl using homebrew:
+
+```shell
+brew install egctl
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+{{% alert title="Next Steps" color="warning" %}}
+
+You can refer to the [Use egctl task](../tasks/operations/egctl) for more details about egctl.
+
+{{% /alert %}}
diff --git a/site/content/en/v1.2/install/install-helm.md b/site/content/en/v1.2/install/install-helm.md
new file mode 100644
index 00000000000..16975efc84d
--- /dev/null
+++ b/site/content/en/v1.2/install/install-helm.md
@@ -0,0 +1,150 @@
++++
+title = "Install with Helm"
+weight = -100
++++
+
+[Helm](https://helm.sh) is a package manager for Kubernetes that automates the release and management of software on Kubernetes.
+
+Envoy Gateway can be installed via a Helm chart with a few simple steps, depending on if you are deploying for the first time, upgrading Envoy Gateway from an existing installation, or migrating from Envoy Gateway.
+
+## Before you begin
+
+{{% alert title="Compatibility Matrix" color="warning" %}}
+Refer to the [Version Compatibility Matrix](/news/releases/matrix) to learn more.
+{{% /alert %}}
+
+The Envoy Gateway Helm chart is hosted by DockerHub.
+
+It is published at `oci://docker.io/envoyproxy/gateway-helm`.
+
+{{% alert title="Note" color="primary" %}}
+We use `v0.0.0-latest` as the latest development version.
+
+You can visit [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gateway-helm/tags) for more releases.
+{{% /alert %}}
+
+## Install with Helm
+
+Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one.
+
+{{% alert title="Developer Guide" color="primary" %}}
+Refer to the [Developer Guide](../../contributions/develop) to learn more.
+{{% /alert %}}
+
+Install the Gateway API CRDs and Envoy Gateway:
+
+```shell
+helm install eg oci://docker.io/envoyproxy/gateway-helm --version {{< helm-version >}} -n envoy-gateway-system --create-namespace
+```
+
+Wait for Envoy Gateway to become available:
+
+```shell
+kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
+```
+
+Install the GatewayClass, Gateway, HTTPRoute and example app:
+
+```shell
+kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/{{< yaml-version >}}/quickstart.yaml -n default
+```
+
+**Note**: [`quickstart.yaml`] defines that Envoy Gateway will listen for
+traffic on port 80 on its globally-routable IP address, to make it easy to use
+browsers to test Envoy Gateway. When Envoy Gateway sees that its Listener is
+using a privileged port (<1024), it will map this internally to an
+unprivileged port, so that Envoy Gateway doesn't need additional privileges.
+It's important to be aware of this mapping, since you may need to take it into
+consideration when debugging.
+
+[`quickstart.yaml`]: https://github.com/envoyproxy/gateway/releases/download/{{< yaml-version >}}/quickstart.yaml
+
+## Upgrading from a previous version
+
+[Helm](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations) does not update CRDs
+that live in the `/crds` folder in the Helm Chart. So you will manually need to update the CRDs.
+Follow the steps outlined in [this](./install-yaml/#upgrading-from-v1.1) section if you're upgrading from a previous version.
+
+## Helm chart customizations
+
+Some of the quick ways of using the helm install command for envoy gateway installation are below.
+
+{{% alert title="Helm Chart Values" color="primary" %}}
+If you want to know all the available fields inside the values.yaml file, please see the [Helm Chart Values](./gateway-helm-api).
+{{% /alert %}}
+
+### Increase the replicas
+
+```shell
+helm install eg oci://docker.io/envoyproxy/gateway-helm --version {{< helm-version >}} -n envoy-gateway-system --create-namespace --set deployment.replicas=2
+```
+
+### Change the kubernetesClusterDomain name
+
+If you have installed your cluster with different domain name you can use below command.
+
+```shell
+helm install eg oci://docker.io/envoyproxy/gateway-helm --version {{< helm-version >}} -n envoy-gateway-system --create-namespace --set kubernetesClusterDomain=
+```
+
+**Note**: Above are some of the ways we can directly use for customization of our installation. But if you are looking for more complex changes [values.yaml](https://helm.sh/docs/chart_template_guide/values_files/) comes to rescue.
+
+### Using values.yaml file for complex installation
+
+```yaml
+deployment:
+ envoyGateway:
+ resources:
+ limits:
+ cpu: 700m
+ memory: 128Mi
+ requests:
+ cpu: 10m
+ memory: 64Mi
+ ports:
+ - name: grpc
+ port: 18005
+ targetPort: 18000
+ - name: ratelimit
+ port: 18006
+ targetPort: 18001
+
+config:
+ envoyGateway:
+ logging:
+ level:
+ default: debug
+```
+
+Here we have made three changes to our values.yaml file. Increase the resources limit for cpu to `700m`, changed the port for grpc to `18005` and for ratelimit to `18006` and also updated the logging level to `debug`.
+
+You can use the below command to install the envoy gateway using values.yaml file.
+
+```shell
+helm install eg oci://docker.io/envoyproxy/gateway-helm --version {{< helm-version >}} -n envoy-gateway-system --create-namespace -f values.yaml
+```
+
+## Open Ports
+
+These are the ports used by Envoy Gateway and the managed Envoy Proxy.
+
+### Envoy Gateway
+
+| Envoy Gateway | Address | Port | Configurable |
+|:----------------------:|:---------:|:------:| :------: |
+| Xds EnvoyProxy Server | 0.0.0.0 | 18000 | No |
+| Xds RateLimit Server | 0.0.0.0 | 18001 | No |
+| Admin Server | 127.0.0.1 | 19000 | Yes |
+| Metrics Server | 0.0.0.0 | 19001 | No |
+| Health Check | 127.0.0.1 | 8081 | No |
+
+### EnvoyProxy
+
+| Envoy Proxy | Address | Port |
+|:---------------------------------:|:-----------:| :-----: |
+| Admin Server | 127.0.0.1 | 19000 |
+| Heath Check | 0.0.0.0 | 19001 |
+
+{{% alert title="Next Steps" color="warning" %}}
+Envoy Gateway should now be successfully installed and running. To experience more abilities of Envoy Gateway, refer to [Tasks](../tasks).
+{{% /alert %}}
diff --git a/site/content/en/v1.2/install/install-yaml.md b/site/content/en/v1.2/install/install-yaml.md
new file mode 100644
index 00000000000..0da5ca9cca1
--- /dev/null
+++ b/site/content/en/v1.2/install/install-yaml.md
@@ -0,0 +1,60 @@
++++
+title = "Install with Kubernetes YAML"
+weight = -99
++++
+
+This task walks you through installing Envoy Gateway in your Kubernetes cluster.
+
+The manual install process does not allow for as much control over configuration
+as the [Helm install method](./install-helm), so if you need more control over your Envoy Gateway
+installation, it is recommended that you use helm.
+
+## Before you begin
+
+Envoy Gateway is designed to run in Kubernetes for production. The most essential requirements are:
+
+* Kubernetes 1.28 or later
+* The `kubectl` command-line tool
+
+{{% alert title="Compatibility Matrix" color="warning" %}}
+Refer to the [Version Compatibility Matrix](/news/releases/matrix) to learn more.
+{{% /alert %}}
+
+## Install with YAML
+
+Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one.
+
+{{% alert title="Developer Guide" color="primary" %}}
+Refer to the [Developer Guide](../../contributions/develop) to learn more.
+{{% /alert %}}
+
+1. In your terminal, run the following command:
+
+ ```shell
+ kubectl apply --server-side -f https://github.com/envoyproxy/gateway/releases/download/{{< yaml-version >}}/install.yaml
+ ```
+
+2. Next Steps
+
+ Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks).
+
+## Upgrading from v1.1
+
+Some manual migration steps are required to upgrade Envoy Gateway to v1.2.
+
+1. Update your `GRPCRoute` and `ReferenceGrant` resources if the storage version being used is `v1alpha2`.
+Follow the steps in Gateway-API [v1.2 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v12-upgrade-notes)
+
+2. Update Gateway-API and Envoy Gateway CRDs:
+
+```shell
+helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-crds.yaml
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated
+```
+
+3. Install Envoy Gateway {{< yaml-version >}}:
+
+```shell
+helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system
+```
diff --git a/site/content/en/v1.2/install/migrating-to-envoy.md b/site/content/en/v1.2/install/migrating-to-envoy.md
new file mode 100644
index 00000000000..470c759ab7e
--- /dev/null
+++ b/site/content/en/v1.2/install/migrating-to-envoy.md
@@ -0,0 +1,143 @@
+---
+title: Migrating from Ingress Resources
+---
+
+## Introduction
+
+Migrating from Ingress to Envoy Gateway involves converting existing Ingress resources into resources compatible with Envoy Gateway. The `ingress2gateway` tool simplifies this migration by transforming Ingress resources into Gateway API resources that Envoy Gateway can use. This guide will walk you through the prerequisites, installation of the `ingress2gateway` tool, and provide an example migration process.
+
+## Prerequisites
+
+Before you start the migration, ensure you have the following:
+
+1. **Envoy Gateway Installed**: You need Envoy Gateway set up in your Kubernetes cluster. Follow the [Envoy Gateway installation guide](../install) for details.
+2. **Kubernetes Cluster Access**: Ensure you have access to your Kubernetes cluster and necessary permissions to manage resources.
+3. **Installation of `ingress2gateway` Tool**: You need to install the `ingress2gateway` tool in your Kubernetes cluster and configure it accordingly. Follow the [ingress2gateway tool installation guide](https://github.com/kubernetes-sigs/ingress2gateway/blob/main/README.md#installation) for details.
+
+## Example Migration
+
+Here’s a step-by-step example of migrating from Ingress to Envoy Gateway using `ingress2gateway`:
+
+### 1. Install and Configure Envoy Gateway
+
+Ensure that Envoy Gateway is installed and running in your cluster. Follow the [official Envoy Gateway installation guide](../install) for setup instructions.
+
+### 2. Create a GatewayClass
+
+To ensure the generated HTTPRoutes are programmed correctly in the Envoy Gateway data plane, create a GatewayClass that links to the Envoy Gateway controller.
+
+Create a `GatewayClass` resource:
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: GatewayClass
+metadata:
+ name: envoy-gateway-class
+spec:
+ controllerName: gateway.envoyproxy.io/controller
+```
+
+Apply this resource:
+
+```sh
+kubectl apply -f gatewayclass.yaml
+```
+
+### 3. Install Ingress2gateway
+
+Ensure you have the Ingress2gateway package installed. If not, follow the package’s installation instructions.
+
+### 4. Run Ingress2gateway
+
+Use Ingress2gateway to read your existing Ingress resources and translate them into Gateway API resources.
+
+```sh
+./ingress2gateway print
+```
+
+This command will:
+1. Read your Kube config file to extract the cluster credentials and the current active namespace.
+2. Search for Ingress and provider-specific resources in that namespace.
+3. Convert them to Gateway API resources (Gateways and HTTPRoutes).
+
+#### Example Ingress Configuration
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: example-ingress
+ namespace: default
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /
+spec:
+ rules:
+ - host: example.com
+ http:
+ paths:
+ - path: /foo
+ pathType: Prefix
+ backend:
+ service:
+ name: foo-service
+ port:
+ number: 80
+```
+
+### 5. Save the Output
+
+The command will output the equivalent Gateway API resources in YAML/JSON format to stdout. Save this output to a file for further use.
+
+```sh
+./ingress2gateway print > gateway-resources.yaml
+```
+
+### 6. Apply the Translated Resources
+
+Apply the translated Gateway API resources to your cluster.
+
+```sh
+kubectl apply -f gateway-resources.yaml
+```
+
+### 7. Create a Gateway Resource
+
+Create a `Gateway` resource specifying the `GatewayClass` created earlier and including the necessary listeners.
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: Gateway
+metadata:
+ name: example-gateway
+ namespace: default
+spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ hostname: example.com
+```
+
+Apply this resource:
+
+```sh
+kubectl apply -f gateway.yaml
+```
+
+### 8. Validate the Migration
+
+Ensure the HTTPRoutes and Gateways are correctly set up and that traffic is being routed as expected. Validate the new configuration by checking the status of the Gateway and HTTPRoute resources.
+
+```sh
+kubectl get gateways
+kubectl get httproutes
+```
+
+### 9. Monitor and Troubleshoot
+
+Monitor the Envoy Gateway logs and metrics to ensure everything is functioning correctly. Troubleshoot any issues by reviewing the Gateway and HTTPRoute statuses and Envoy Gateway controller logs.
+
+## Summary
+
+By following this guide, users can effectively migrate their existing Ingress resources to Envoy Gateway using the Ingress2gateway package. Creating a GatewayClass and linking it to the Envoy Gateway controller ensures that the translated resources are properly programmed in the data plane, providing a seamless transition to the Envoy Gateway environment.
\ No newline at end of file
diff --git a/site/content/en/v1.2/tasks/_index.md b/site/content/en/v1.2/tasks/_index.md
new file mode 100644
index 00000000000..49e8595328b
--- /dev/null
+++ b/site/content/en/v1.2/tasks/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Tasks"
+weight: 2
+description: Learn Envoy Gateway hands-on through tasks
+---
diff --git a/site/content/en/v1.2/tasks/extensibility/_index.md b/site/content/en/v1.2/tasks/extensibility/_index.md
new file mode 100644
index 00000000000..664c734aeca
--- /dev/null
+++ b/site/content/en/v1.2/tasks/extensibility/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Extensibility"
+weight: 4
+description: This section includes Extensibility tasks.
+---
diff --git a/site/content/en/v1.2/tasks/extensibility/build-wasm-image.md b/site/content/en/v1.2/tasks/extensibility/build-wasm-image.md
new file mode 100644
index 00000000000..dfe983dd193
--- /dev/null
+++ b/site/content/en/v1.2/tasks/extensibility/build-wasm-image.md
@@ -0,0 +1,71 @@
+---
+title: "Build a Wasm image"
+---
+
+Envoy Gateway supports two types of Wasm extensions within the [EnvoyExtensionPolicy][] API: HTTP Wasm Extensions and Image Wasm Extensions.
+Packaging a Wasm extension as an OCI image is beneficial because it simplifies versioning and distribution for users.
+Additionally, users can leverage existing image toolchain to build and manage Wasm images.
+
+This document describes how to build OCI images which are consumable by Envoy Gateway.
+
+## Wasm Image Formats
+
+There are two types of images that are supported by Envoy Gateway. One is in the Docker format, and another is the standard
+OCI specification compliant format. Please note that both of them are supported by any OCI registries. You can choose
+either format depending on your preference, and both types of images are consumable by Envoy Gateway [EnvoyExtensionPolicy][] API.
+
+## Build Wasm Docker image
+
+We assume that you have a valid Wasm binary named `plugin.wasm`. Then you can build a Wasm Docker image with the Docker CLI.
+
+1. First, we prepare the following Dockerfile:
+
+```
+$ cat Dockerfile
+FROM scratch
+
+COPY plugin.wasm ./
+```
+
+**Note: you must have exactly one `COPY` instruction in the Dockerfile in order to end up having only one layer in produced images.**
+
+2. Then, build your image via `docker build` command
+
+```
+$ docker build . -t my-registry/mywasm:0.1.0
+```
+
+3. Finally, push the image to your registry via `docker push` command
+
+```
+$ docker push my-registry/mywasm:0.1.0
+```
+
+## Build Wasm OCI image
+
+We assume that you have a valid Wasm binary named `plugin.wasm`, and you have [buildah](https://buildah.io/) installed on your machine.
+Then you can build a Wasm OCI image with the `buildah` CLI.
+
+1. First, we create a working container from `scratch` base image with `buildah from` command.
+
+```
+$ buildah --name mywasm from scratch
+mywasm
+```
+
+2. Then copy the Wasm binary into that base image by `buildah copy` command to create the layer.
+
+```
+$ buildah copy mywasm plugin.wasm ./
+af82a227630327c24026d7c6d3057c3d5478b14426b74c547df011ca5f23d271
+```
+
+**Note: you must execute `buildah copy` exactly once in order to end up having only one layer in produced images**
+
+4. Now, you can build an OCI image and push it to your registry via `buildah commit` command
+
+```
+$ buildah commit mywasm docker://my-remote-registry/mywasm:0.1.0
+```
+
+[EnvoyExtensionPolicy]: ../../../api/extension_types#envoyextensionpolicy
diff --git a/site/content/en/v1.2/tasks/extensibility/envoy-patch-policy.md b/site/content/en/v1.2/tasks/extensibility/envoy-patch-policy.md
new file mode 100644
index 00000000000..9fddf7dc576
--- /dev/null
+++ b/site/content/en/v1.2/tasks/extensibility/envoy-patch-policy.md
@@ -0,0 +1,428 @@
+---
+title: "Envoy Patch Policy"
+---
+
+This task explains the usage of the [EnvoyPatchPolicy][] API.
+__Note:__ This API is meant for users extremely familiar with Envoy [xDS][] semantics.
+Also before considering this API for production use cases, please be aware that this API
+is unstable and the outcome may change across versions. Use at your own risk.
+
+## Introduction
+
+The [EnvoyPatchPolicy][] API allows user to modify the output [xDS][]
+configuration generated by Envoy Gateway intended for EnvoyProxy,
+using [JSON Patch][] semantics.
+
+## Motivation
+
+This API was introduced to allow advanced users to be able to leverage Envoy Proxy functionality
+not exposed by Envoy Gateway APIs today.
+
+## Quickstart
+
+### Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+### Enable EnvoyPatchPolicy
+
+* By default [EnvoyPatchPolicy][] is disabled. Lets enable it in the [EnvoyGateway][] startup configuration
+
+* The default installation of Envoy Gateway installs a default [EnvoyGateway][] configuration and attaches it
+using a `ConfigMap`. In the next step, we will update this resource to enable EnvoyPatchPolicy.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{< boilerplate rollout-envoy-gateway >}}
+
+## Testing
+
+### Customize Response
+
+* Use EnvoyProxy's [Local Reply Modification][] feature to return a custom response back to the client when
+the status code is `404`
+
+* Apply the configuration
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <//
+ name: default/eg/http
+ operation:
+ op: add
+ path: "/default_filter_chain/filters/0/typed_config/local_reply_config"
+ value:
+ mappers:
+ - filter:
+ status_code_filter:
+ comparison:
+ op: EQ
+ value:
+ default_value: 404
+ runtime_key: key_b
+ status_code: 406
+ body:
+ inline_string: "could not find what you are looking for"
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyPatchPolicy
+metadata:
+ name: custom-response-patch-policy
+ namespace: default
+spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
+ type: JSONPatch
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.listener.v3.Listener"
+ # The listener name is of the form //
+ name: default/eg/http
+ operation:
+ op: add
+ path: "/default_filter_chain/filters/0/typed_config/local_reply_config"
+ value:
+ mappers:
+ - filter:
+ status_code_filter:
+ comparison:
+ op: EQ
+ value:
+ default_value: 404
+ runtime_key: key_b
+ status_code: 406
+ body:
+ inline_string: "could not find what you are looking for"
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+When mergeGateways is enabled, there will be one Envoy deployment for all Gateways in the cluster.
+Then the EnvoyPatchPolicy should target a specific GatewayClass.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <//
+ name: default/eg/http
+ operation:
+ op: add
+ path: "/default_filter_chain/filters/0/typed_config/local_reply_config"
+ value:
+ mappers:
+ - filter:
+ status_code_filter:
+ comparison:
+ op: EQ
+ value:
+ default_value: 404
+ runtime_key: key_b
+ status_code: 406
+ body:
+ inline_string: "could not find what you are looking for"
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyPatchPolicy
+metadata:
+ name: custom-response-patch-policy
+ namespace: default
+spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: GatewayClass
+ name: eg
+ type: JSONPatch
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.listener.v3.Listener"
+ # The listener name is of the form //
+ name: default/eg/http
+ operation:
+ op: add
+ path: "/default_filter_chain/filters/0/typed_config/local_reply_config"
+ value:
+ mappers:
+ - filter:
+ status_code_filter:
+ comparison:
+ op: EQ
+ value:
+ default_value: 404
+ runtime_key: key_b
+ status_code: 406
+ body:
+ inline_string: "could not find what you are looking for"
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+* Edit the HTTPRoute resource from the Quickstart to only match on paths with value `/get`
+
+```shell
+kubectl patch httproute backend --type=json --patch '
+ - op: add
+ path: /spec/rules/0/matches/0/path/value
+ value: /get
+ '
+```
+
+* Test it out by specifying a path apart from `/get`
+
+```shell
+$ curl --header "Host: www.example.com" http://$GATEWAY_HOST/find
+Handling connection for 8888
+could not find what you are looking for
+```
+
+### Customize VirtualHost by name
+
+* Use EnvoyProxy's `include_attempt_count_in_response` feature to include the attempt count as header in the downstream response.
+* Apply the configuration
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <//
+ name: default/eg/http
+ operation:
+ op: add
+ # Every virtual_host that ends with 'www_example_com' (using RegEx Filter)
+ jsonPath: "..virtual_hosts[?match(@.name, '.*www_example_com')]"
+ # If the property does not exists, it can not be selected with jsonPath
+ # Therefore the new property must be set in path
+ path: "include_attempt_count_in_response"
+ value: true
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyPatchPolicy
+metadata:
+ name: include-attempts
+ namespace: default
+spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
+ type: JSONPatch
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
+ # The RouteConfiguration name is of the form //
+ name: default/eg/http
+ operation:
+ op: add
+ # Every virtual_host that ends with 'www_example_com' (using RegEx Filter)
+ jsonPath: "..virtual_hosts[?match(@.name, '.*www_example_com')]"
+ # If the property does not exists, it can not be selected with jsonPath
+ # Therefore the new property must be set in path
+ path: "include_attempt_count_in_response"
+ value: true
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+* Test it out by looking at the response headers
+
+```
+$ curl -v --header "Host: www.example.com" http://localhost:8888/
+...
+< x-envoy-attempt-count: 1
+...
+```
+
+## Debugging
+
+### Runtime
+
+* The `Status` subresource should have information about the status of the resource. Make sure
+`Accepted=True` and `Programmed=True` conditions are set to ensure that the policy has been
+applied to Envoy Proxy.
+
+```yaml
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyPatchPolicy
+metadata:
+ annotations:
+ kubectl.kubernetes.io/last-applied-configuration: |
+ {"apiVersion":"gateway.envoyproxy.io/v1alpha1","kind":"EnvoyPatchPolicy","metadata":{"annotations":{},"name":"custom-response-patch-policy","namespace":"default"},"spec":{"jsonPatches":[{"name":"default/eg/http","operation":{"op":"add","path":"/default_filter_chain/filters/0/typed_config/local_reply_config","value":{"mappers":[{"body":{"inline_string":"could not find what you are looking for"},"filter":{"status_code_filter":{"comparison":{"op":"EQ","value":{"default_value":404}}}}}]}},"type":"type.googleapis.com/envoy.config.listener.v3.Listener"}],"priority":0,"targetRef":{"group":"gateway.networking.k8s.io","kind":"Gateway","name":"eg","namespace":"default"},"type":"JSONPatch"}}
+ creationTimestamp: "2023-07-31T21:47:53Z"
+ generation: 1
+ name: custom-response-patch-policy
+ namespace: default
+ resourceVersion: "10265"
+ uid: a35bda6e-a0cc-46d7-a63a-cee765174bc3
+spec:
+ jsonPatches:
+ - name: default/eg/http
+ operation:
+ op: add
+ path: /default_filter_chain/filters/0/typed_config/local_reply_config
+ value:
+ mappers:
+ - body:
+ inline_string: could not find what you are looking for
+ filter:
+ status_code_filter:
+ comparison:
+ op: EQ
+ value:
+ default_value: 404
+ type: type.googleapis.com/envoy.config.listener.v3.Listener
+ priority: 0
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
+ type: JSONPatch
+status:
+ conditions:
+ - lastTransitionTime: "2023-07-31T21:48:19Z"
+ message: EnvoyPatchPolicy has been accepted.
+ observedGeneration: 1
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: "2023-07-31T21:48:19Z"
+ message: successfully applied patches.
+ reason: Programmed
+ status: "True"
+ type: Programmed
+```
+
+### Offline
+
+* You can use [egctl x translate][] to validate the translated xds output.
+
+## Caveats
+
+This API will always be an unstable API and the same outcome cannot be guaranteed
+across versions for these reasons
+* The Envoy Proxy API might deprecate and remove API fields
+* Envoy Gateway might alter the xDS translation creating a different xDS output
+such as changing the `name` field of resources.
+
+[EnvoyPatchPolicy]: ../../../api/extension_types#envoypatchpolicy
+[EnvoyGateway]: ../../../api/extension_types#envoygateway
+[JSON Patch]: https://datatracker.ietf.org/doc/html/rfc6902
+[xDS]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/operations/dynamic_configuration
+[Local Reply Modification]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/local_reply
+[egctl x translate]: ../operations/egctl#egctl-experimental-translate
diff --git a/site/content/en/v1.2/tasks/extensibility/ext-proc.md b/site/content/en/v1.2/tasks/extensibility/ext-proc.md
new file mode 100644
index 00000000000..910332f4740
--- /dev/null
+++ b/site/content/en/v1.2/tasks/extensibility/ext-proc.md
@@ -0,0 +1,283 @@
+---
+title: "External Processing"
+---
+
+This task provides instructions for configuring external processing.
+
+External processing calls an external gRPC service to process HTTP requests and responses.
+The external processing service can inspect and mutate requests and responses.
+
+Envoy Gateway introduces a new CRD called [EnvoyExtensionPolicy][] that allows the user to configure external processing.
+This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute][HTTPRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## GRPC External Processing Service
+
+### Installation
+
+Install a demo GRPC service that will be used as the external processing service:
+
+```shell
+kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/ext-proc-grpc-service.yaml
+```
+
+Create a new HTTPRoute resource to route traffic on the path `/myapp` to the backend service.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the HTTPRoute status:
+
+```shell
+kubectl get httproute/myapp -o yaml
+```
+
+### Configuration
+
+Create a new EnvoyExtensionPolicy resource to configure the external processing service. This EnvoyExtensionPolicy targets the HTTPRoute
+"myApp" created in the previous step. It calls the GRPC external processing service "grpc-ext-proc" on port 9002 for
+processing.
+
+By default, requests and responses are not sent to the external processor. The `processingMode` struct is used to define what should be sent to the external processor.
+In this example, we configure the following processing modes:
+* The empty `request` field configures envoy to send request headers to the external processor.
+* The `response` field includes configuration for body processing. As a result, response headers are sent to the external processor. Additionally, the response body is streamed to the external processor.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the Envoy Extension Policy configuration:
+
+```shell
+kubectl get envoyextensionpolicy/ext-proc-example -o yaml
+```
+
+
+Because the gRPC external processing service is enabled with TLS, a [BackendTLSPolicy][] needs to be created to configure
+the communication between the Envoy proxy and the gRPC auth service.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the BackendTLSPolicy configuration:
+
+```shell
+kubectl get backendtlspolicy/grpc-ext-proc-btls -o yaml
+```
+
+### Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+Send a request to the backend service without `Authentication` header:
+
+```shell
+curl -v -H "Host: www.example.com" "http://${GATEWAY_HOST}/myapp"
+```
+
+You should see that the external processor added headers:
+- `x-request-ext-processed` - this header was added before the request was forwarded to the backend
+- `x-response-ext-processed`- this header was added before the response was returned to the client
+
+
+```
+curl -v -H "Host: www.example.com" http://localhost:10080/myapp
+[...]
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< date: Fri, 14 Jun 2024 19:30:40 GMT
+< content-length: 502
+< x-response-ext-processed: true
+<
+{
+ "path": "/myapp",
+ "host": "www.example.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+[...]
+ "X-Request-Ext-Processed": [
+ "true"
+ ],
+[...]
+ }
+```
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the demo auth services, HTTPRoute, EnvoyExtensionPolicy and BackendTLSPolicy:
+
+```shell
+kubectl delete -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/ext-proc-grpc-service.yaml
+kubectl delete httproute/myapp
+kubectl delete envoyextensionpolicy/ext-proc-example
+kubectl delete backendtlspolicy/grpc-ext-proc-btls
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[EnvoyExtensionPolicy]: ../../../api/extension_types#envoyextensionpolicy
+[BackendTLSPolicy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
diff --git a/site/content/en/v1.2/tasks/extensibility/extension-server.md b/site/content/en/v1.2/tasks/extensibility/extension-server.md
new file mode 100644
index 00000000000..6d16013d410
--- /dev/null
+++ b/site/content/en/v1.2/tasks/extensibility/extension-server.md
@@ -0,0 +1,209 @@
+---
+title: "Envoy Gateway Extension Server"
+linkTitle: "Extension Server"
+---
+
+This task explains how to extend Envoy Gateway using an Extension Server. Envoy Gateway
+can be configured to call an external server over gRPC with the xDS configuration _before_
+it is sent to Envoy Proxy. The external server can modify the provided configuration
+programmatically using any semantics supported by the [xDS][] API.
+
+Using an extension server allows vendors to add xDS configuration that Envoy Gateway itself
+doesn't support with a very high level of control over the generated xDS configuration.
+
+**Note:** Modifying the xDS configuration generated by Envoy Gateway may break functionality
+configured by native Envoy Gateway means. Like other cases where the xDS configuration
+is modified outside of Envoy Gateway's control, this is risky and should be tested thoroughly,
+especially when using the same extension server across different Envoy Gateway versions.
+
+## Introduction
+
+One of the Envoy Gateway project goals is to "provide a common foundation for vendors to
+build value-added products without having to re-engineer fundamental interactions". The
+Envoy Gateway Extension Server provides a mechanism where Envoy Gateway tracks all provider
+resources and then calls a set of hooks that allow the generated xDS configuration to be
+modified before it is sent to Envoy Proxy. See the [design documentation][] for full details.
+
+This task sets up an example extension server that adds the Envoy Proxy Basic Authentication
+HTTP filter to all the listeners generated by Envoy Gateway. The example extension server
+includes its own CRD which allows defining username/password pairs that will be accepted by
+the Envoy Proxy.
+
+**Note:** Envoy Gateway supports adding Basic Authentication to routes using a [SecurityPolicy][].
+See [this task](../security/basic-auth) for the preferred way to configure Basic
+Authentication.
+
+
+## Quickstart
+
+### Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+### Build and run the example Extension Server
+
+Build and deploy the example extension server in the `examples/extension-server` folder into the cluster
+running Envoy Gateway.
+
+* Build the extension server image
+
+ **Note:** The provided `Makefile` builds an image with the name `extension-server:latest`. You may need to create
+a different tag for it in order to allow Kubernetes to pull it correctly.
+
+ ```shell
+ make image
+ ```
+
+* Publish the extension server image in your docker repository
+
+ {{< tabpane text=true >}}
+ {{% tab header="local kind server" %}}
+
+ ```shell
+ kind load docker-image --name envoy-gateway extension-server:latest
+ ```
+
+ {{% /tab %}}
+ {{% tab header="other Kubernetes server" %}}
+
+ ```shell
+ docker tag extension-server:latest $YOUR_DOCKER_REPO
+ docker push $YOUR_DOCKER_REPO
+ ```
+
+ {{% /tab %}}
+ {{< /tabpane >}}
+
+* Deploy the extension server in your cluster
+
+ If you are using your own docker image repository, make sure to update the `values.yaml` with the correct
+image name and tag.
+
+ ```shell
+ helm install -n envoy-gateway-system extension-server ./examples/extension-server/charts/extension-server
+ ```
+
+### Configure Envoy Gateway
+
+* Grant Envoy Gateway's `ServiceAccount` permission to access the extension server's CRD
+
+ ```shell
+ kubectl create clusterrole listener-context-example-viewer \
+ --verb=get,list,watch \
+ --resource=ListenerContextExample
+
+ kubectl create clusterrolebinding envoy-gateway-listener-context \
+ --clusterrole=listener-context-example-viewer \
+ --serviceaccount=envoy-gateway-system:envoy-gateway
+ ```
+
+* Configure Envoy Gateway to use the Extension Server
+
+ Add the following fragment to Envoy Gateway's [configuration][] file:
+
+ ```yaml
+ extensionManager:
+ # Envoy Gateway will watch these resource kinds and use them as extension policies
+ # which can be attached to Gateway resources.
+ policyResources:
+ - group: example.extensions.io
+ version: v1alpha1
+ kind: ListenerContextExample
+ hooks:
+ # The type of hooks that should be invoked
+ xdsTranslator:
+ post:
+ - HTTPListener
+ service:
+ # The service that is hosting the extension server
+ fqdn:
+ hostname: extension-server.envoy-gateway-system.svc.cluster.local
+ port: 5005
+ ```
+
+ After updating Envoy Gateway's configuration file, restart Envoy Gateway.
+
+## Testing
+
+Get the Gateway's address:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+The extension server adds the Basic Authentication HTTP filter to all listeners configured by
+Envoy Gateway. Initially there are no valid user/password combinations available. Accessing the
+example backend should fail with a 401 status:
+
+```console
+$ curl -v --header "Host: www.example.com" "http://${GATEWAY_HOST}/example"
+...
+> GET /example HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/7.81.0
+> Accept: */*
+>
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 401 Unauthorized
+< www-authenticate: Basic realm="http://www.example.com/example"
+< content-length: 58
+< content-type: text/plain
+< date: Mon, 08 Jul 2024 10:53:11 GMT
+<
+...
+User authentication failed. Missing username and password.
+...
+```
+
+Add a new Username/Password combination using the example extension server's CRD:
+
+```shell
+kubectl apply -f - << EOF
+apiVersion: example.extensions.io/v1alpha1
+kind: ListenerContextExample
+metadata:
+ name: listeneruser
+spec:
+ targetRefs:
+ - kind: Gateway
+ name: eg
+ group: gateway.networking.k8s.io
+ username: user
+ password: p@ssw0rd
+EOF
+```
+
+Authenticating with this user/password combination will now work.
+
+```console
+$ curl -v http://${GATEWAY_HOST}/example -H "Host: www.example.com" --user 'user:p@ssw0rd'
+...
+> GET /example HTTP/1.1
+> Host: www.example.com
+> Authorization: Basic dXNlcm5hbWU6cEBzc3cwcmQ=
+> User-Agent: curl/7.81.0
+> Accept: */*
+>
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< date: Mon, 08 Jul 2024 10:56:17 GMT
+< content-length: 559
+<
+...
+ "headers": {
+ "Authorization": [
+ "Basic dXNlcm5hbWU6cEBzc3cwcmQ="
+ ],
+ "X-Example-Ext": [
+ "user"
+ ],
+...
+```
+
+
+[xDS]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/operations/dynamic_configuration
+[design documentation]: /contributions/design/extending-envoy-gateway
+[SecurityPolicy]: /latest/api/extension_types/#securitypolicy
+[configuration]: /latest/api/extension_types/#extensionmanager
diff --git a/site/content/en/v1.2/tasks/extensibility/wasm.md b/site/content/en/v1.2/tasks/extensibility/wasm.md
new file mode 100644
index 00000000000..baad6a5804f
--- /dev/null
+++ b/site/content/en/v1.2/tasks/extensibility/wasm.md
@@ -0,0 +1,187 @@
+---
+title: "Wasm Extensions"
+---
+
+This task provides instructions for extending Envoy Gateway with WebAssembly (Wasm) extensions.
+
+Wasm extensions allow you to extend the functionality of Envoy Gateway by running custom code against HTTP requests and responses,
+without modifying the Envoy Gateway binary. These extensions can be written in any language that compiles to Wasm, such as C++, Rust, AssemblyScript, or TinyGo.
+
+Envoy Gateway introduces a new CRD called [EnvoyExtensionPolicy][] that allows the user to configure Wasm extensions.
+This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute][HTTPRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## Configuration
+
+Envoy Gateway supports two types of Wasm extensions:
+* HTTP Wasm Extension: The Wasm extension is fetched from a remote URL.
+* Image Wasm Extension: The Wasm extension is packaged as an OCI image and fetched from an image registry.
+
+The following example demonstrates how to configure an [EnvoyExtensionPolicy][] to attach a Wasm extension to an [EnvoyExtensionPolicy][] .
+This Wasm extension adds a custom header `x-wasm-custom: FOO` to the response.
+
+### HTTP Wasm Extension
+
+This [EnvoyExtensionPolicy][] configuration fetches the Wasm extension from an HTTP URL.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the EnvoyExtensionPolicy status:
+
+```shell
+kubectl get envoyextensionpolicy/http-wasm-source-test -o yaml
+```
+
+### Image Wasm Extension
+
+This [EnvoyExtensionPolicy][] configuration fetches the Wasm extension from an OCI image.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the EnvoyExtensionPolicy status:
+
+```shell
+kubectl get envoyextensionpolicy/http-wasm-source-test -o yaml
+```
+
+### Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+Send a request to the backend service:
+
+```shell
+curl -i -H "Host: www.example.com" "http://${GATEWAY_HOST}"
+```
+
+You should see that the wasm extension has added this header to the response:
+
+```
+x-wasm-custom: FOO
+```
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the EnvoyExtensionPolicy:
+
+```shell
+kubectl delete envoyextensionpolicy/wasm-test
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[EnvoyExtensionPolicy]: ../../../api/extension_types#envoyextensionpolicy
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
diff --git a/site/content/en/v1.2/tasks/observability/_index.md b/site/content/en/v1.2/tasks/observability/_index.md
new file mode 100644
index 00000000000..9ca4896ee8b
--- /dev/null
+++ b/site/content/en/v1.2/tasks/observability/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Observability"
+weight: 4
+description: This section includes Observability tasks.
+---
diff --git a/site/content/en/v1.2/tasks/observability/gateway-api-metrics.md b/site/content/en/v1.2/tasks/observability/gateway-api-metrics.md
new file mode 100644
index 00000000000..bf799616aff
--- /dev/null
+++ b/site/content/en/v1.2/tasks/observability/gateway-api-metrics.md
@@ -0,0 +1,58 @@
+---
+title: "Gateway API Metrics"
+---
+
+Resource metrics for Gateway API objects are available using the [Gateway API State Metrics][gasm] project.
+The project also provides example dashboard for visualising the metrics using Grafana, and example alerts using Prometheus & Alertmanager.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+Run the following commands to install the metrics stack, with the Gateway API State Metrics configuration, on your kubernetes cluster:
+
+```shell
+kubectl apply --server-side -f https://raw.githubusercontent.com/Kuadrant/gateway-api-state-metrics/main/config/examples/kube-prometheus/bundle_crd.yaml
+kubectl apply -f https://raw.githubusercontent.com/Kuadrant/gateway-api-state-metrics/main/config/examples/kube-prometheus/bundle.yaml
+```
+
+## Metrics and Alerts
+
+To access the Prometheus UI, wait for the statefulset to be ready, then use the port-forward command:
+
+```shell
+# This first command may fail if the statefulset has not been created yet.
+# In that case, try again until you get a message like 'Waiting for 2 pods to be ready...'
+# or 'statefulset rolling update complete 2 pods...'
+kubectl -n monitoring rollout status --watch --timeout=5m statefulset/prometheus-k8s
+kubectl -n monitoring port-forward service/prometheus-k8s 9090:9090 > /dev/null &
+```
+
+Navigate to `http://localhost:9090`.
+Metrics can be queried from the 'Graph' tab e.g. `gatewayapi_gateway_created`
+See the [Gateway API State Metrics README][gasm-readme] for the full list of Gateway API metrics available.
+
+Alerts can be seen in the 'Alerts' tab.
+Gateway API specific alerts will be grouped under the 'gateway-api.rules' heading.
+
+***Note:*** Alerts are defined in a PrometheusRules custom resource in the 'monitoring' namespace. You can modify the alert rules by updating this resource.
+
+## Dashboards
+
+To view the dashboards in Grafana, wait for the deployment to be ready, then use the port-forward command:
+
+```shell
+kubectl -n monitoring wait --timeout=5m deployment/grafana --for=condition=Available
+kubectl -n monitoring port-forward service/grafana 3000:3000 > /dev/null &
+```
+
+Navigate to `http://localhost:3000` and sign in with admin/admin.
+The Gateway API State dashboards will be available in the 'Default' folder and tagged with 'gateway-api'.
+See the [Gateway API State Metrics README][gasm-dashboards] for further information on available dashboards.
+
+***Note:*** Dashboards are loaded from configmaps. You can modify the dashboards in the Grafana UI, however you will need to export them from the UI and update the json in the configmaps to persist changes.
+
+
+[gasm]: https://github.com/Kuadrant/gateway-api-state-metrics
+[gasm-readme]: https://github.com/Kuadrant/gateway-api-state-metrics/tree/main#metrics
+[gasm-dashboards]: https://github.com/Kuadrant/gateway-api-state-metrics/tree/main#dashboards
diff --git a/site/content/en/v1.2/tasks/observability/gateway-exported-metrics.md b/site/content/en/v1.2/tasks/observability/gateway-exported-metrics.md
new file mode 100644
index 00000000000..cf04f1d444b
--- /dev/null
+++ b/site/content/en/v1.2/tasks/observability/gateway-exported-metrics.md
@@ -0,0 +1,97 @@
+---
+title: "Gateway Exported Metrics"
+---
+
+The Envoy Gateway provides a collection of self-monitoring metrics in [Prometheus format][prom-format].
+
+These metrics allow monitoring of the behavior of Envoy Gateway itself (as distinct from that of the EnvoyProxy it managed).
+
+{{% alert title="EnvoyProxy Metrics" color="warning" %}}
+For EnvoyProxy Metrics, please refer to the [EnvoyProxy Metrics](./proxy-metric) to learn more.
+{{% /alert %}}
+
+## Watching Components
+
+The Resource Provider, xDS Translator and Infra Manager etc. are key components that made up of Envoy Gateway,
+they all follow the design of [Watching Components](../../../contributions/design/watching).
+
+Envoy Gateway collects the following metrics in Watching Components:
+
+| Name | Description |
+|----------------------------------------|--------------------------------------------------------------|
+| `watchable_depth` | Current depth of watchable map. |
+| `watchable_subscribe_duration_seconds` | How long in seconds a subscribed watchable queue is handled. |
+| `watchable_subscribe_total` | Total number of subscribed watchable queue. |
+
+Each metric includes the `runner` label to identify the corresponding components,
+the relationship between label values and components is as follows:
+
+| Value | Components |
+|--------------------|---------------------------------|
+| `gateway-api` | Gateway API Translator |
+| `infrastructure` | Infrastructure Manager |
+| `xds-server` | xDS Server |
+| `xds-translator` | xDS Translator |
+| `global-ratelimit` | Global RateLimit xDS Translator |
+
+Metrics may include one or more additional labels, such as `message`, `status` and `reason` etc.
+
+## Status Updater
+
+Envoy Gateway monitors the status updates of various resources (like `GatewayClass`, `Gateway` and `HTTPRoute` etc.) through Status Updater.
+
+Envoy Gateway collects the following metrics in Status Updater:
+
+| Name | Description |
+|----------------------------------|------------------------------------------------|
+| `status_update_total` | Total number of status update by object kind. |
+| `status_update_duration_seconds` | How long a status update takes to finish. |
+
+Each metric includes `kind` label to identify the corresponding resources.
+
+## xDS Server
+
+Envoy Gateway monitors the cache and xDS connection status in xDS Server.
+
+Envoy Gateway collects the following metrics in xDS Server:
+
+| Name | Description |
+|-------------------------------|--------------------------------------------------------|
+| `xds_snapshot_create_total` | Total number of xds snapshot cache creates. |
+| `xds_snapshot_update_total` | Total number of xds snapshot cache updates by node id. |
+| `xds_stream_duration_seconds` | How long a xds stream takes to finish. |
+
+- For xDS snapshot cache update and xDS stream connection status, each metric includes `nodeID` label to identify the connection peer.
+- For xDS stream connection status, each metric also includes `streamID` label to identify the connection stream, and `isDeltaStream` label to identify the delta connection stream.
+
+## Infrastructure Manager
+
+Envoy Gateway monitors the `apply` (`create` or `update`) and `delete` operations in Infrastructure Manager.
+
+Envoy Gateway collects the following metrics in Infrastructure Manager:
+
+| Name | Description |
+|------------------------------------|---------------------------------------------------------|
+| `resource_apply_total` | Total number of applied resources. |
+| `resource_apply_duration_seconds` | How long in seconds a resource be applied successfully. |
+| `resource_delete_total` | Total number of deleted resources. |
+| `resource_delete_duration_seconds` | How long in seconds a resource be deleted successfully. |
+
+Each metric includes the `kind` label to identify the corresponding resources being applied or deleted by Infrastructure Manager.
+
+Metrics may also include `name` and `namespace` label to identify the name and namespace of corresponding Infrastructure Manager.
+
+## Wasm
+
+Envoy Gateway monitors the status of Wasm remote fetch cache.
+
+| Name | Description |
+|---------------------------|--------------------------------------------------|
+| `wasm_cache_entries` | Number of Wasm remote fetch cache entries. |
+| `wasm_cache_lookup_total` | Total number of Wasm remote fetch cache lookups. |
+| `wasm_remote_fetch_total` | Total number of Wasm remote fetches and results. |
+
+For metric `wasm_cache_lookup_total`, we are using `hit` label (boolean) to indicate whether the Wasm cache has been hit.
+
+
+[prom-format]: https://prometheus.io/docs/instrumenting/exposition_formats/#text-based-format
diff --git a/site/content/en/v1.2/tasks/observability/gateway-observability.md b/site/content/en/v1.2/tasks/observability/gateway-observability.md
new file mode 100644
index 00000000000..f23eb9097cf
--- /dev/null
+++ b/site/content/en/v1.2/tasks/observability/gateway-observability.md
@@ -0,0 +1,168 @@
+---
+title: "Gateway Observability"
+---
+
+Envoy Gateway provides observability for the ControlPlane and the underlying EnvoyProxy instances.
+This task show you how to config gateway control-plane observability, includes metrics.
+
+## Prerequisites
+
+{{< boilerplate o11y_prerequisites >}}
+
+## Metrics
+
+The default installation of Envoy Gateway installs a default [EnvoyGateway][] configuration and attaches it
+using a `ConfigMap`. In this section, we will update this resource to enable various ways to retrieve metrics
+from Envoy Gateway.
+
+{{% alert title="Exported Metrics" color="warning" %}}
+Refer to the [Gateway Exported Metrics List](./gateway-exported-metrics) to learn more about Envoy Gateway's Metrics.
+{{% /alert %}}
+
+### Retrieve Prometheus Metrics from Envoy Gateway
+
+By default, prometheus metric is enabled. You can directly retrieve metrics from Envoy Gateway:
+
+```shell
+export ENVOY_POD_NAME=$(kubectl get pod -n envoy-gateway-system --selector=control-plane=envoy-gateway,app.kubernetes.io/instance=eg -o jsonpath='{.items[0].metadata.name}')
+kubectl port-forward pod/$ENVOY_POD_NAME -n envoy-gateway-system 19001:19001
+
+# check metrics
+curl localhost:19001/metrics
+```
+
+The following is an example to disable prometheus metric for Envoy Gateway.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{< boilerplate rollout-envoy-gateway >}}
+
+### Enable Open Telemetry sink in Envoy Gateway
+
+The following is an example to send metric via Open Telemetry sink to OTEL gRPC Collector.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{< boilerplate rollout-envoy-gateway >}}
+
+Verify OTel-Collector metrics:
+
+```shell
+export OTEL_POD_NAME=$(kubectl get pod -n monitoring --selector=app.kubernetes.io/name=opentelemetry-collector -o jsonpath='{.items[0].metadata.name}')
+kubectl port-forward pod/$OTEL_POD_NAME -n monitoring 19001:19001
+
+# check metrics
+curl localhost:19001/metrics
+```
+
+[EnvoyGateway]: ../../api/extension_types#envoygateway
diff --git a/site/content/en/v1.2/tasks/observability/grafana-integration.md b/site/content/en/v1.2/tasks/observability/grafana-integration.md
new file mode 100644
index 00000000000..259f6958bf0
--- /dev/null
+++ b/site/content/en/v1.2/tasks/observability/grafana-integration.md
@@ -0,0 +1,87 @@
+---
+title: "Visualising metrics using Grafana"
+---
+
+Envoy Gateway provides support for exposing Envoy Gateway and Envoy Proxy metrics to a Prometheus instance.
+This task shows you how to visualise the metrics exposed to Prometheus using Grafana.
+
+## Prerequisites
+
+{{< boilerplate o11y_prerequisites >}}
+
+Follow the steps from the [Gateway Observability](./gateway-observability) and [Proxy Metrics](./proxy-metric) to enable Prometheus metrics
+for both Envoy Gateway (Control Plane) and Envoy Proxy (Data Plane).
+
+Expose endpoints:
+
+```shell
+GRAFANA_IP=$(kubectl get svc grafana -n monitoring -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
+```
+
+## Connecting Grafana with Prometheus datasource
+
+To visualise metrics from Prometheus, we have to connect Grafana with Prometheus. If you installed Grafana follow the command
+from prerequisites sections, the Prometheus datasource should be already configured.
+
+You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure-prometheus-data-source/).
+
+## Accessing Grafana
+
+You can access the Grafana instance by visiting `http://{GRAFANA_IP}`, derived in prerequisites.
+
+To log in to Grafana, use the credentials `admin:admin`.
+
+Envoy Gateway has examples of dashboard for you to get started, you can check them out under `Dashboards/envoy-gateway`.
+
+If you'd like import Grafana dashboards on your own, please refer to Grafana docs for [importing dashboards](https://grafana.com/docs/grafana/latest/dashboards/manage-dashboards/#import-a-dashboard).
+
+### Envoy Proxy Global
+
+This dashboard example shows the overall downstream and upstream stats for each Envoy Proxy instance.
+
+![Envoy Proxy Global](/img/envoy-proxy-global-dashboard.png)
+
+### Envoy Clusters
+
+This dashboard example shows the overall stats for each cluster from Envoy Proxy fleet.
+
+![Envoy Clusters](/img/envoy-clusters-dashboard.png)
+
+### Envoy Gateway Global
+
+This dashboard example shows the overall stats exported by Envoy Gateway fleet.
+
+![Envoy Gateway Global: Watching Components](/img/envoy-gateway-global-watching-components.png)
+
+![Envoy Gateway Global: Status Updater](/img/envoy-gateway-global-status-updater.png)
+
+![Envoy Gateway Global: xDS Server](/img/envoy-gateway-global-xds-server.png)
+
+![Envoy Gateway Global: Infrastructure Manager](/img/envoy-gateway-global-infra-manager.png)
+
+### Resources Monitor
+
+This dashboard example shows the overall resources stats for both Envoy Gateway and Envoy Proxy fleet.
+
+![Envoy Gateway Resources](/img/resources-monitor-dashboard.png)
+
+## Update Dashboards
+
+All dashboards of Envoy Gateway are maintained under `charts/gateway-addons-helm/dashboards`,
+feel free to make [contributions](../../../contributions/CONTRIBUTING).
+
+### Grafonnet
+
+Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html).
+This is the preferred method for any new dashboards.
+
+You can run `make helm-generate.gateway-addons-helm` to generate new version of dashboards.
+All the generated dashboards have a `.gen.json` suffix.
+
+### Legacy Dashboards
+
+Many of our older dashboards are manually created in the UI and exported as JSON and checked in.
+
+These example dashboards cannot be updated in-place by default, if you are trying to
+make some changes to the older dashboards, you can save them directly as a JSON file
+and then re-import.
diff --git a/site/content/en/v1.2/tasks/observability/proxy-accesslog.md b/site/content/en/v1.2/tasks/observability/proxy-accesslog.md
new file mode 100644
index 00000000000..17d444b8636
--- /dev/null
+++ b/site/content/en/v1.2/tasks/observability/proxy-accesslog.md
@@ -0,0 +1,310 @@
+---
+title: "Proxy Access Logs"
+---
+
+Envoy Gateway provides observability for the ControlPlane and the underlying EnvoyProxy instances.
+This task show you how to config proxy access logs.
+
+## Prerequisites
+
+{{< boilerplate o11y_prerequisites >}}
+
+By default, the Service type of `loki` is ClusterIP, you can change it to LoadBalancer type for further usage:
+
+```shell
+kubectl patch service loki -n monitoring -p '{"spec": {"type": "LoadBalancer"}}'
+```
+
+Expose endpoints:
+
+```shell
+LOKI_IP=$(kubectl get svc loki -n monitoring -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
+```
+
+## Default Access Log
+
+If custom format string is not specified, Envoy Gateway uses the following default format:
+
+```json
+{
+ "start_time": "%START_TIME%",
+ "method": "%REQ(:METHOD)%",
+ "x-envoy-origin-path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%",
+ "protocol": "%PROTOCOL%",
+ "response_code": "%RESPONSE_CODE%",
+ "response_flags": "%RESPONSE_FLAGS%",
+ "response_code_details": "%RESPONSE_CODE_DETAILS%",
+ "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%",
+ "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%",
+ "bytes_received": "%BYTES_RECEIVED%",
+ "bytes_sent": "%BYTES_SENT%",
+ "duration": "%DURATION%",
+ "x-envoy-upstream-service-time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%",
+ "x-forwarded-for": "%REQ(X-FORWARDED-FOR)%",
+ "user-agent": "%REQ(USER-AGENT)%",
+ "x-request-id": "%REQ(X-REQUEST-ID)%",
+ ":authority": "%REQ(:AUTHORITY)%",
+ "upstream_host": "%UPSTREAM_HOST%",
+ "upstream_cluster": "%UPSTREAM_CLUSTER%",
+ "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%",
+ "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%",
+ "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%",
+ "requested_server_name": "%REQUESTED_SERVER_NAME%",
+ "route_name": "%ROUTE_NAME%"
+}
+```
+
+> Note: Envoy Gateway disable envoy headers by default, you can enable it by setting `EnableEnvoyHeaders` to `true` in the [ClientTrafficPolicy](../../api/extension_types#backendtrafficpolicy) CRD.
+
+
+Verify logs from loki:
+
+```shell
+curl -s "http://$LOKI_IP:3100/loki/api/v1/query_range" --data-urlencode "query={job=\"fluentbit\"}" | jq '.data.result[0].values'
+```
+
+## Disable Access Log
+
+If you want to disable it, set the `telemetry.accesslog.disable` to `true` in the `EnvoyProxy` CRD.
+
+```shell
+kubectl apply -f - <}}
+
+## Metrics
+
+By default, Envoy Gateway expose metrics with prometheus endpoint.
+
+Verify metrics:
+
+```shell
+export ENVOY_POD_NAME=$(kubectl get pod -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+kubectl port-forward pod/$ENVOY_POD_NAME -n envoy-gateway-system 19001:19001
+
+# check metrics
+curl localhost:19001/stats/prometheus | grep "default/backend/rule/0"
+```
+
+You can disable metrics by setting the `telemetry.metrics.prometheus.disable` to `true` in the `EnvoyProxy` CRD.
+
+```shell
+kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/metric/disable-prometheus.yaml
+```
+
+Envoy Gateway can send metrics to OpenTelemetry Sink.
+Send metrics to OTel-Collector:
+
+```shell
+kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/metric/otel-sink.yaml
+```
+
+Verify OTel-Collector metrics:
+
+```shell
+export OTEL_POD_NAME=$(kubectl get pod -n monitoring --selector=app.kubernetes.io/name=opentelemetry-collector -o jsonpath='{.items[0].metadata.name}')
+kubectl port-forward pod/$OTEL_POD_NAME -n monitoring 19001:19001
+
+# check metrics
+curl localhost:19001/metrics | grep "default/backend/rule/0"
+```
diff --git a/site/content/en/v1.2/tasks/observability/proxy-trace.md b/site/content/en/v1.2/tasks/observability/proxy-trace.md
new file mode 100644
index 00000000000..39243d329bc
--- /dev/null
+++ b/site/content/en/v1.2/tasks/observability/proxy-trace.md
@@ -0,0 +1,293 @@
+---
+title: "Proxy Tracing"
+---
+
+Envoy Gateway provides observability for the ControlPlane and the underlying EnvoyProxy instances.
+This task show you how to config proxy tracing.
+
+## Prerequisites
+
+{{< boilerplate o11y_prerequisites >}}
+
+Expose Tempo endpoints:
+
+```shell
+TEMPO_IP=$(kubectl get svc tempo -n monitoring -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
+```
+
+## Traces
+
+By default, Envoy Gateway doesn't send traces to any sink.
+You can enable traces by setting the `telemetry.tracing` in the [EnvoyProxy][envoy-proxy-crd] CRD.
+Currently, Envoy Gateway support OpenTelemetry, [Zipkin](../../api/extension_types#zipkintracingprovider) and Datadog tracer.
+
+### Tracing Provider
+
+The following configurations show how to apply proxy with different providers:
+
+{{< tabpane text=true >}}
+{{% tab header="OpenTelemetry" %}}
+
+```shell
+kubectl apply -f - <}}
+
+Query trace by trace id:
+
+```shell
+curl -s "http://$TEMPO_IP:3100/api/traces/" | jq
+```
+
+
+### Sampling Rate
+
+Envoy Gateway use 100% sample rate, which means all requests will be traced.
+This may cause performance issues when traffic is very high, you can adjust
+the sample rate by setting the `telemetry.tracing.samplingRate` in the [EnvoyProxy][envoy-proxy-crd] CRD.
+
+The following configurations show how to apply proxy with 1% sample rates:
+
+```shell
+kubectl apply -f - <}}
+
+Follow the steps from the [Global Rate Limit](../traffic/global-rate-limit) to install RateLimit.
+
+## Traces
+
+By default, the Envoy Gateway does not configure RateLimit to send traces to the OpenTelemetry Sink.
+You can configure the collector in the `rateLimit.telemetry.tracing` of the `EnvoyGateway`CRD.
+
+RateLimit uses the OpenTelemetry Exporter to export traces to the collector.
+You can configure a collector that supports the OTLP protocol, which includes but is not limited to: OpenTelemetry Collector, Jaeger, Zipkin, and so on.
+
+***Note:***
+
+* By default, the Envoy Gateway configures a `100%` sampling rate for RateLimit, which may lead to performance issues.
+
+Assuming the OpenTelemetry Collector is running in the `observability` namespace, and it has a service named `otel-svc`,
+we only want to sample `50%` of the trace data. We would configure it as follows:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{< boilerplate rollout-envoy-gateway >}}
diff --git a/site/content/en/v1.2/tasks/operations/_index.md b/site/content/en/v1.2/tasks/operations/_index.md
new file mode 100644
index 00000000000..d87097c7d1e
--- /dev/null
+++ b/site/content/en/v1.2/tasks/operations/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Operations"
+weight: 4
+description: This section includes Operations tasks.
+---
diff --git a/site/content/en/v1.2/tasks/operations/customize-envoyproxy.md b/site/content/en/v1.2/tasks/operations/customize-envoyproxy.md
new file mode 100644
index 00000000000..9c5ab5fe177
--- /dev/null
+++ b/site/content/en/v1.2/tasks/operations/customize-envoyproxy.md
@@ -0,0 +1,1095 @@
+---
+title: "Customize EnvoyProxy"
+---
+
+Envoy Gateway provides an [EnvoyProxy][] CRD that can be linked to the ParametersRef
+in a Gateway and GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
+Service. To learn more about GatewayClass and ParametersRef, please refer to [Gateway API documentation][].
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+Before you start, you need to add `Infrastructure.ParametersRef` in Gateway, and refer to EnvoyProxy Config:
+**Note**: `MergeGateways` cannot be set to `true` in your EnvoyProxy config if attaching to the Gateway.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+You can also attach the EnvoyProxy resource to the GatewayClass using the `parametersRef` field.
+This configuration is discouraged if you plan on creating multiple Gateways linking to the same
+GatewayClass and would like different infrastructure configurations for each of them.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+## Customize EnvoyProxy Deployment Replicas
+
+You can customize the EnvoyProxy Deployment Replicas via EnvoyProxy Config like:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After you apply the config, you should see the replicas of envoyproxy changes to 2.
+And also you can dynamically change the value.
+
+``` shell
+kubectl get deployment -l gateway.envoyproxy.io/owning-gateway-name=eg -n envoy-gateway-system
+```
+
+## Customize EnvoyProxy Image
+
+You can customize the EnvoyProxy Image via EnvoyProxy Config like:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After applying the config, you can get the deployment image, and see it has changed.
+
+## Customize EnvoyProxy Pod Annotations
+
+You can customize the EnvoyProxy Pod Annotations via EnvoyProxy Config like:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After applying the config, you can get the envoyproxy pods, and see new annotations has been added.
+
+## Customize EnvoyProxy Deployment Resources
+
+You can customize the EnvoyProxy Deployment Resources via EnvoyProxy Config like:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+## Customize EnvoyProxy Deployment Env
+
+You can customize the EnvoyProxy Deployment Env via EnvoyProxy Config like:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+> Envoy Gateway has provided two initial `env` `ENVOY_GATEWAY_NAMESPACE` and `ENVOY_POD_NAME` for envoyproxy container.
+
+After applying the config, you can get the envoyproxy deployment, and see resources has been changed.
+
+## Customize EnvoyProxy Deployment Volumes or VolumeMounts
+
+You can customize the EnvoyProxy Deployment Volumes or VolumeMounts via EnvoyProxy Config like:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After applying the config, you can get the envoyproxy deployment, and see resources has been changed.
+
+## Customize EnvoyProxy Service Annotations
+
+You can customize the EnvoyProxy Service Annotations via EnvoyProxy Config like:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After applying the config, you can get the envoyproxy service, and see annotations has been added.
+
+## Customize EnvoyProxy Bootstrap Config
+
+You can customize the EnvoyProxy bootstrap config via EnvoyProxy Config.
+There are three ways to customize it:
+
+* Replace: the whole bootstrap config will be replaced by the config you provided.
+* Merge: the config you provided will be merged into the default bootstrap config.
+* JSONPatch: the list of JSON Patches you provided will be applied to the bootstrap config. JSON Patch is a standard format specified in [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902/).
+
+{{< tabpane text=true >}}
+{{% tab header="Replace: apply from stdin" %}}
+
+```shell
+cat <}}
+
+You can use [egctl x translate][]
+to get the default xDS Bootstrap configuration used by Envoy Gateway.
+
+After applying the config, the bootstrap config will be overridden by the new config you provided.
+Any errors in the configuration will be surfaced as status within the `GatewayClass` resource.
+You can also validate this configuration using [egctl x translate][].
+
+## Customize EnvoyProxy Horizontal Pod Autoscaler
+
+You can enable [Horizontal Pod Autoscaler](https://github.com/envoyproxy/gateway/issues/703) for EnvoyProxy Deployment. However, before enabling the HPA for EnvoyProxy, please ensure that the [metrics-server](https://github.com/kubernetes-sigs/metrics-server) component is installed in the cluster.
+
+Once confirmed, you can apply it via EnvoyProxy Config as shown below:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After applying the config, the EnvoyProxy HPA (Horizontal Pod Autoscaler) is generated. However, upon activating the EnvoyProxy's HPA, the Envoy Gateway will no longer reference the `replicas` field specified in the `envoyDeployment`, as outlined [here](#customize-envoyproxy-deployment-replicas).
+
+## Customize EnvoyProxy Command line options
+
+You can customize the EnvoyProxy Command line options via `spec.extraArgs` in EnvoyProxy Config.
+For example, the following configuration will add `--disable-extensions` arg in order to disable `envoy.access_loggers/envoy.access_loggers.wasm` extension:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+## Customize EnvoyProxy with Patches
+
+You can customize the EnvoyProxy using patches.
+
+### Patching Deployment for EnvoyProxy
+
+For example, the following configuration will add resource limits to the `envoy` and the `shutdown-manager` containers in the `envoyproxy` deployment:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After applying the configuration, you will see the change in both containers in the `envoyproxy` deployment.
+
+### Patching Service for EnvoyProxy
+
+For example, the following configuration will add an annotation for the `envoyproxy` service:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After applying the configuration, you will see the `custom-annotation: foobar` has been added to the `envoyproxy` service.
+
+## Customize Filter Order
+
+Under the hood, Envoy Gateway uses a series of [Envoy HTTP filters](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/http_filters)
+to process HTTP requests and responses, and to apply various policies.
+
+By default, Envoy Gateway applies the following filters in the order shown:
+* envoy.filters.http.fault
+* envoy.filters.http.cors
+* envoy.filters.http.ext_authz
+* envoy.filters.http.basic_authn
+* envoy.filters.http.oauth2
+* envoy.filters.http.jwt_authn
+* envoy.filters.http.ext_proc
+* envoy.filters.http.wasm
+* envoy.filters.http.rbac
+* envoy.filters.http.local_ratelimit
+* envoy.filters.http.ratelimit
+* envoy.filters.http.router
+
+The default order in which these filters are applied is opinionated and may not suit all use cases.
+To address this, Envoy Gateway allows you to adjust the execution order of these filters with the `filterOrder` field in the [EnvoyProxy][] resource.
+
+`filterOrder` is a list of customized filter order configurations. Each configuration can specify a filter
+name and a filter to place it before or after. These configurations are applied in the order they are listed.
+If a filter occurs in multiple configurations, the final order is the result of applying all these configurations in order.
+To avoid conflicts, it is recommended to only specify one configuration per filter.
+
+For example, the following configuration moves the `envoy.filters.http.wasm` filter before the `envoy.filters.http.jwt_authn`
+filter and the `envoy.filters.http.cors` filter after the `envoy.filters.http.basic_authn` filter:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+## Customize EnvoyProxy IP Family
+
+You can customize the IP family configuration for EnvoyProxy via the EnvoyProxy Config.
+This allows the Envoy Proxy fleet to serve external clients over IPv4 as well as IPv6.
+
+The below configuration sets the `ipFamily` to `DualStack` to allow ingressing IPv4 as well as IPv6 traffic.
+
+**Note**: Envoy Gateway relies on the [Service](https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services) spec of the BackendRef resource (linked to xRoutes) to decide which type of IP addresses to use to route to them.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+After applying the config, the EnvoyProxy deployment will be configured to use the specified IP family. When set to `DualStack`, both IPv4 and IPv6 networking will be enabled.
+
+**Note**: Your cluster must support the selected IP family configuration. For DualStack support, ensure your Kubernetes cluster is properly configured for dual-stack networking.
+
+[Gateway API documentation]: https://gateway-api.sigs.k8s.io/
+[EnvoyProxy]: ../../../api/extension_types#envoyproxy
+[egctl x translate]: ../operations/egctl#egctl-experimental-translate
\ No newline at end of file
diff --git a/site/content/en/v1.2/tasks/operations/deployment-mode.md b/site/content/en/v1.2/tasks/operations/deployment-mode.md
new file mode 100644
index 00000000000..c50d65b2863
--- /dev/null
+++ b/site/content/en/v1.2/tasks/operations/deployment-mode.md
@@ -0,0 +1,1072 @@
+---
+title: "Deployment Mode"
+---
+## Deployment modes
+
+### One GatewayClass per Envoy Gateway Controller
+* An Envoy Gateway is associated with a single [GatewayClass][] resource under one controller.
+This is the simplest deployment mode and is suitable for scenarios where each Gateway needs to have its own dedicated set of resources and configurations.
+
+### Multiple GatewayClasses per Envoy Gateway Controller
+* An Envoy Gateway is associated with multiple [GatewayClass][] resources under one controller.
+* Support for accepting multiple GatewayClasses was added [here][issue1231].
+
+### Separate Envoy Gateway Controllers
+If you've instantiated multiple GatewayClasses, you can also run separate Envoy Gateway controllers in different namespaces, linking a GatewayClass to each of them for multi-tenancy.
+Please follow the example [Multi-tenancy](#multi-tenancy).
+
+### Merged Gateways onto a single EnvoyProxy fleet
+By default, each Gateway has its own dedicated set of Envoy Proxy and its configurations.
+However, for some deployments, it may be more convenient to merge listeners across multiple Gateways and deploy a single Envoy Proxy fleet.
+
+This can help to efficiently utilize the infra resources in the cluster and manage them in a centralized manner, or have a single IP address for all of the listeners.
+Setting the `mergeGateways` field in the EnvoyProxy resource linked to GatewayClass will result in merging all Gateway listeners under one GatewayClass resource.
+
+* The tuple of port, protocol, and hostname must be unique across all Listeners.
+
+Please follow the example [Merged gateways deployment](#merged-gateways-deployment).
+
+### Supported Modes
+
+#### Kubernetes
+
+* The default deployment model is - Envoy Gateway **watches** for resources such a `Service` & `HTTPRoute` in **all** namespaces
+and **creates** managed data plane resources such as EnvoyProxy `Deployment` in the **namespace where Envoy Gateway is running**.
+* Envoy Gateway also supports [Namespaced deployment mode][], you can watch resources in the specific namespaces by assigning
+`EnvoyGateway.provider.kubernetes.watch.namespaces` or `EnvoyGateway.provider.kubernetes.watch.namespaceSelector` and **creates** managed data plane resources in the **namespace where Envoy Gateway is running**.
+* Support for alternate deployment modes is being tracked [here][issue1117].
+
+### Multi-tenancy
+
+#### Kubernetes
+
+* A `tenant` is a group within an organization (e.g. a team or department) who shares organizational resources. We recommend
+each `tenant` deploy their own Envoy Gateway controller in their respective `namespace`. Below is an example of deploying Envoy Gateway
+by the `marketing` and `product` teams in separate namespaces.
+
+* Lets deploy Envoy Gateway in the `marketing` namespace and also watch resources only in this namespace. We are also setting the controller name to a unique string here `gateway.envoyproxy.io/marketing-gatewayclass-controller`.
+
+```shell
+helm install \
+--set config.envoyGateway.gateway.controllerName=gateway.envoyproxy.io/marketing-gatewayclass-controller \
+--set config.envoyGateway.provider.kubernetes.watch.type=Namespaces \
+--set config.envoyGateway.provider.kubernetes.watch.namespaces={marketing} \
+eg-marketing oci://docker.io/envoyproxy/gateway-helm \
+--version {{< helm-version >}} -n marketing --create-namespace
+```
+
+Lets create a `GatewayClass` linked to the marketing team's Envoy Gateway controller, and as well other resources linked to it, so the `backend` application operated by this team can be exposed to external clients.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Lets port forward to the generated envoy proxy service in the `marketing` namespace and send a request to it.
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n marketing --selector=gateway.envoyproxy.io/owning-gateway-namespace=marketing,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+kubectl -n marketing port-forward service/${ENVOY_SERVICE} 8888:8080 &
+```
+
+```shell
+curl --verbose --header "Host: www.marketing.example.com" http://localhost:8888/get
+```
+
+```console
+* Trying 127.0.0.1:8888...
+* Connected to localhost (127.0.0.1) port 8888 (#0)
+> GET /get HTTP/1.1
+> Host: www.marketing.example.com
+> User-Agent: curl/7.86.0
+> Accept: */*
+>
+Handling connection for 8888
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< date: Thu, 20 Apr 2023 19:19:42 GMT
+< content-length: 521
+< x-envoy-upstream-service-time: 0
+< server: envoy
+<
+{
+ "path": "/get",
+ "host": "www.marketing.example.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/7.86.0"
+ ],
+ "X-Envoy-Expected-Rq-Timeout-Ms": [
+ "15000"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "10.1.0.157"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "c637977c-458a-48ae-92b3-f8c429849322"
+ ]
+ },
+ "namespace": "marketing",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-74888f465f-bcs8f"
+* Connection #0 to host localhost left intact
+```
+
+* Lets deploy Envoy Gateway in the `product` namespace and also watch resources only in this namespace.
+
+```shell
+helm install \
+--set config.envoyGateway.gateway.controllerName=gateway.envoyproxy.io/product-gatewayclass-controller \
+--set config.envoyGateway.provider.kubernetes.watch.type=Namespaces \
+--set config.envoyGateway.provider.kubernetes.watch.namespaces={product} \
+eg-product oci://docker.io/envoyproxy/gateway-helm \
+--version {{< helm-version >}} -n product --create-namespace
+```
+
+Lets create a `GatewayClass` linked to the product team's Envoy Gateway controller, and as well other resources linked to it, so the `backend` application operated by this team can be exposed to external clients.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Lets port forward to the generated envoy proxy service in the `product` namespace and send a request to it.
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n product --selector=gateway.envoyproxy.io/owning-gateway-namespace=product,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+kubectl -n product port-forward service/${ENVOY_SERVICE} 8889:8080 &
+```
+
+```shell
+curl --verbose --header "Host: www.product.example.com" http://localhost:8889/get
+```
+
+```shell
+* Trying 127.0.0.1:8889...
+* Connected to localhost (127.0.0.1) port 8889 (#0)
+> GET /get HTTP/1.1
+> Host: www.product.example.com
+> User-Agent: curl/7.86.0
+> Accept: */*
+>
+Handling connection for 8889
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< date: Thu, 20 Apr 2023 19:20:17 GMT
+< content-length: 517
+< x-envoy-upstream-service-time: 0
+< server: envoy
+<
+{
+ "path": "/get",
+ "host": "www.product.example.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/7.86.0"
+ ],
+ "X-Envoy-Expected-Rq-Timeout-Ms": [
+ "15000"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "10.1.0.156"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "39196453-2250-4331-b756-54003b2853c2"
+ ]
+ },
+ "namespace": "product",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-74888f465f-64fjs"
+* Connection #0 to host localhost left intact
+```
+
+With the below command you can ensure that you are no able to access the marketing team's backend exposed using the `www.marketing.example.com` hostname
+and the product team's data plane.
+
+```shell
+curl --verbose --header "Host: www.marketing.example.com" http://localhost:8889/get
+```
+
+```console
+* Trying 127.0.0.1:8889...
+* Connected to localhost (127.0.0.1) port 8889 (#0)
+> GET /get HTTP/1.1
+> Host: www.marketing.example.com
+> User-Agent: curl/7.86.0
+> Accept: */*
+>
+Handling connection for 8889
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 404 Not Found
+< date: Thu, 20 Apr 2023 19:22:13 GMT
+< server: envoy
+< content-length: 0
+<
+* Connection #0 to host localhost left intact
+```
+
+### Merged gateways deployment
+
+In this example, we will deploy GatewayClass
+
+```shell
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+ name: merged-eg
+spec:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parametersRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyProxy
+ name: custom-proxy-config
+ namespace: envoy-gateway-system
+```
+
+with a referenced [EnvoyProxy][] resource configured to enable merged Gateways deployment mode.
+
+```shell
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+ name: custom-proxy-config
+ namespace: envoy-gateway-system
+spec:
+ mergeGateways: true
+```
+
+#### Deploy merged-gateways example
+
+Deploy resources on your cluster from the example.
+
+```shell
+kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/merged-gateways.yaml
+```
+
+Verify that Gateways are deployed and programmed
+
+```shell
+kubectl get gateways -n default
+
+NAMESPACE NAME CLASS ADDRESS PROGRAMMED AGE
+default merged-eg-1 merged-eg 172.18.255.202 True 2m4s
+default merged-eg-2 merged-eg 172.18.255.202 True 2m4s
+default merged-eg-3 merged-eg 172.18.255.202 True 2m4s
+```
+
+Verify that HTTPRoutes are deployed
+
+```shell
+kubectl get httproute -n default
+NAMESPACE NAME HOSTNAMES AGE
+default hostname1-route ["www.merged1.com"] 2m4s
+default hostname2-route ["www.merged2.com"] 2m4s
+default hostname3-route ["www.merged3.com"] 2m4s
+```
+
+If you take a look at the deployed Envoy Proxy service you would notice that all of the Gateway listeners ports are added to that service.
+
+```shell
+kubectl get service -n envoy-gateway-system
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+envoy-gateway ClusterIP 10.96.141.4 18000/TCP,18001/TCP 6m43s
+envoy-gateway-metrics-service ClusterIP 10.96.113.191 19001/TCP 6m43s
+envoy-merged-eg-668ac7ae LoadBalancer 10.96.48.255 172.18.255.202 8081:30467/TCP,8082:31793/TCP,8080:31153/TCP 3m17s
+```
+
+There should be also one deployment (envoy-merged-eg-668ac7ae-775f9865d-55zhs) for every Gateway and its name should reference the name of the GatewayClass.
+
+```shell
+kubectl get pods -n envoy-gateway-system
+NAME READY STATUS RESTARTS AGE
+envoy-gateway-5d998778f6-wr6m9 1/1 Running 0 6m43s
+envoy-merged-eg-668ac7ae-775f9865d-55zhs 2/2 Running 0 3m17s
+```
+
+#### Testing the Configuration
+
+Get the name of the merged gateways Envoy service:
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gatewayclass=merged-eg -o jsonpath='{.items[0].metadata.name}')
+```
+
+Fetch external IP of the service:
+
+```shell
+export GATEWAY_HOST=$(kubectl get svc/${ENVOY_SERVICE} -n envoy-gateway-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
+```
+
+In certain environments, the load balancer may be exposed using a hostname, instead of an IP address. If so, replace
+`ip` in the above command with `hostname`.
+
+Curl the route hostname-route2 through Envoy proxy:
+
+```shell
+curl --header "Host: www.merged2.com" http://$GATEWAY_HOST:8081/example2
+```
+
+```shell
+{
+ "path": "/example2",
+ "host": "www.merged2.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/8.4.0"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "172.18.0.2"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "deed2767-a483-4291-9429-0e256ab3a65f"
+ ]
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "merged-backend-64ddb65fd7-ttv5z"
+}
+```
+
+Curl the route hostname-route1 through Envoy proxy:
+
+```shell
+curl --header "Host: www.merged1.com" http://$GATEWAY_HOST:8080/example
+```
+
+```shell
+{
+ "path": "/example",
+ "host": "www.merged1.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/8.4.0"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "172.18.0.2"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "20a53440-6327-4c3c-bc8b-8e79e7311043"
+ ]
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "merged-backend-64ddb65fd7-ttv5z"
+}
+```
+
+#### Verify deployment of multiple GatewayClass
+
+Install the GatewayClass, Gateway, HTTPRoute and example app from [Quickstart][] example:
+
+```shell
+kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/{{< yaml-version >}}/quickstart.yaml -n default
+```
+
+Lets create also and additional `Gateway` linked to the GatewayClass and `backend` application from Quickstart example.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify that Gateways are deployed and programmed
+
+```shell
+kubectl get gateways -n default
+```
+
+```shell
+NAME CLASS ADDRESS PROGRAMMED AGE
+eg eg 172.18.255.203 True 114s
+eg-2 eg 172.18.255.204 True 89s
+merged-eg-1 merged-eg 172.18.255.202 True 8m33s
+merged-eg-2 merged-eg 172.18.255.202 True 8m33s
+merged-eg-3 merged-eg 172.18.255.202 True 8m33s
+```
+
+Verify that HTTPRoutes are deployed
+
+```shell
+kubectl get httproute -n default
+```
+
+```shell
+NAMESPACE NAME HOSTNAMES AGE
+default backend ["www.example.com"] 2m29s
+default eg-2 ["www.quickstart.example.com"] 87s
+default hostname1-route ["www.merged1.com"] 10m4s
+default hostname2-route ["www.merged2.com"] 10m4s
+default hostname3-route ["www.merged3.com"] 10m4s
+```
+
+Verify that services are now deployed separately.
+
+```shell
+kubectl get service -n envoy-gateway-system
+```
+
+```shell
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+envoy-default-eg-2-7e515b2f LoadBalancer 10.96.121.46 172.18.255.204 8080:32705/TCP 3m27s
+envoy-default-eg-e41e7b31 LoadBalancer 10.96.11.244 172.18.255.203 80:31930/TCP 2m26s
+envoy-gateway ClusterIP 10.96.141.4 18000/TCP,18001/TCP 14m25s
+envoy-gateway-metrics-service ClusterIP 10.96.113.191 19001/TCP 14m25s
+envoy-merged-eg-668ac7ae LoadBalancer 10.96.243.32 172.18.255.202 8082:31622/TCP,8080:32262/TCP,8081:32305/TCP 10m59s
+```
+
+There should be two deployments for each of newly deployed Gateway and its name should reference the name of the namespace and the Gateway.
+
+```shell
+kubectl get pods -n envoy-gateway-system
+```
+
+```shell
+NAME READY STATUS RESTARTS AGE
+envoy-default-eg-2-7e515b2f-8c98fdf88-p6jhg 2/2 Running 0 3m27s
+envoy-default-eg-e41e7b31-6f998d85d7-jpvmj 2/2 Running 0 2m26s
+envoy-gateway-5d998778f6-wr6m9 1/1 Running 0 14m25s
+envoy-merged-eg-668ac7ae-5958f7b7f6-9h9v2 2/2 Running 0 10m59s
+```
+
+#### Testing the Configuration
+
+Get the name of the merged gateways Envoy service:
+
+```shell
+export DEFAULT_ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+```
+
+Fetch external IP of the service:
+
+```shell
+export DEFAULT_GATEWAY_HOST=$(kubectl get svc/${DEFAULT_ENVOY_SERVICE} -n envoy-gateway-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
+```
+
+Curl the route Quickstart backend route through Envoy proxy:
+
+```shell
+curl --header "Host: www.example.com" http://$DEFAULT_GATEWAY_HOST
+```
+
+```shell
+{
+ "path": "/",
+ "host": "www.example.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/8.4.0"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "172.18.0.2"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "70a40595-67a1-4776-955b-2dee361baed7"
+ ]
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-96f75bbf-6w67z"
+}
+```
+
+Curl the route hostname-route3 through Envoy proxy:
+
+```shell
+curl --header "Host: www.merged3.com" http://$GATEWAY_HOST:8082/example3
+```
+
+```shell
+{
+ "path": "/example3",
+ "host": "www.merged3.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/8.4.0"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "172.18.0.2"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "47aeaef3-abb5-481a-ab92-c2ae3d0862d6"
+ ]
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "merged-backend-64ddb65fd7-k84gv"
+}
+```
+
+[Quickstart]: ../quickstart.md
+[EnvoyProxy]: ../../api/extension_types#envoyproxy
+[GatewayClass]: https://gateway-api.sigs.k8s.io/api-types/gatewayclass/
+[Namespaced deployment mode]: ../../api/extension_types#kuberneteswatchmode
+[issue1231]: https://github.com/envoyproxy/gateway/issues/1231
+[issue1117]: https://github.com/envoyproxy/gateway/issues/1117
diff --git a/site/content/en/v1.2/tasks/operations/egctl.md b/site/content/en/v1.2/tasks/operations/egctl.md
new file mode 100644
index 00000000000..36c1f9979e2
--- /dev/null
+++ b/site/content/en/v1.2/tasks/operations/egctl.md
@@ -0,0 +1,906 @@
+---
+title: "Use egctl"
+---
+
+`egctl` is a command line tool to provide additional functionality for Envoy Gateway users.
+
+## egctl experimental translate
+
+This subcommand allows users to translate from an input configuration type to an output configuration type.
+
+The `translate` subcommand can translate Kubernetes resources to:
+* Gateway API resources
+ This is useful in order to see how validation would occur if these resources were applied to Kubernetes.
+
+ Use the `--to gateway-api` parameter to translate to Gateway API resources.
+
+* Envoy Gateway intermediate representation (IR)
+ This represents Envoy Gateway's translation of the Gateway API resources.
+
+ Use the `--to ir` parameter to translate to Envoy Gateway intermediate representation.
+
+* Envoy Proxy xDS
+ This is the xDS configuration provided to Envoy Proxy.
+
+ Use the `--to xds` parameter to translate to Envoy Proxy xDS.
+
+
+In the below example, we will translate the Kubernetes resources (including the Gateway API resources) into xDS
+resources.
+
+```shell
+cat < Note: If CRDs are already installed, then we need to specify `--skip-crds` to avoid repeated installation of CRDs resources.
+
+```bash
+egctl x install --name shop-backend --namespace shop
+```
+
+
+## egctl experimental uninstall
+
+This subcommand can be used to uninstall envoy-gateway.
+
+```bash
+egctl x uninstall
+```
+
+By default, this will only uninstall the envoy-gateway workload resource, if we want to also uninstall CRDs, we need to specify `--with-crds`
+
+```bash
+egctl x uninstall --with-crds
+```
\ No newline at end of file
diff --git a/site/content/en/v1.2/tasks/operations/standalone-deployment-mode.md b/site/content/en/v1.2/tasks/operations/standalone-deployment-mode.md
new file mode 100644
index 00000000000..cc8218a2905
--- /dev/null
+++ b/site/content/en/v1.2/tasks/operations/standalone-deployment-mode.md
@@ -0,0 +1,123 @@
+---
+title: "Standalone Deployment Mode"
+---
+
+{{% alert title="Notice" color="warning" %}}
+
+Standalone mode is an experimental feature, please **DO NOT** use it in production.
+
+{{% /alert %}}
+
+Envoy Gateway also supports running in standalone mode. In this mode, Envoy Gateway
+does not need to rely on Kubernetes and can be deployed directly on bare metal or virtual machines.
+
+Currently, Envoy Gateway only support the file provider and the host infrastructure provider combinations.
+
+- The file provider will configure the Envoy Gateway to get all gateway-api resources from file system.
+- The host infrastructure provider will configure the Envoy Gateway to deploy one Envoy Proxy as a host process.
+
+## Quick Start
+
+In this quick-start, we will run Envoy Gateway in standalone mode with the file provider
+and the host infrastructure provider.
+
+### Prerequisites
+
+Create a local directory just for testing:
+
+```shell
+mkdir -p /tmp/envoy-gateway-test
+```
+
+Download the Envoy Gateway binary from v1.2.x release.
+
+### Create Certificates
+
+All runners in Envoy Gateway are using TLS connection, so create these TLS certificates locally to
+ensure the Envoy Gateway works properly.
+
+```shell
+envoy-gateway certgen --local
+```
+
+### Start Envoy Gateway
+
+Start Envoy Gateway by the following command:
+
+```shell
+envoy-gateway server --config-path standalone.yaml
+```
+
+with `standalone.yaml` configuration:
+
+```yaml
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyGateway
+gateway:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+provider:
+ type: Custom
+ custom:
+ resource:
+ type: File
+ file:
+ paths: ["/tmp/envoy-gateway-test"]
+ infrastructure:
+ type: Host
+ host: {}
+logging:
+ level:
+ default: info
+extensionApis:
+ enableBackend: true
+```
+
+As you can see, we have enabled the [Backend][] API, this API will be used to represent our local endpoints.
+
+### Trigger an Update
+
+Any changes under watched `paths` will be considered as an update by the file provider.
+
+For instance, copying example file into `/tmp/envoy-gateway-test/` will trigger an update of gateway-api resources:
+
+```shell
+cp examples/standalone/quickstart.yaml /tmp/envoy-gateway-test/quickstart.yaml
+```
+
+From the Envoy Gateway log, you should be able to observe that the Envoy Proxy has been started, and its admin address has been returned.
+
+### Test Connection
+
+Starts a simple local server as an endpoint:
+
+```shell
+python3 -m http.server 3000
+```
+
+Curl the example server through Envoy Proxy:
+
+```shell
+curl --verbose --header "Host: www.example.com" http://0.0.0.0:8888/
+```
+
+```console
+* Trying 0.0.0.0:8888...
+* Connected to 0.0.0.0 (127.0.0.1) port 8888 (#0)
+> GET / HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/7.81.0
+> Accept: */*
+>
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 200 OK
+< server: SimpleHTTP/0.6 Python/3.10.12
+< date: Sat, 26 Oct 2024 13:20:34 GMT
+< content-type: text/html; charset=utf-8
+< content-length: 1870
+<
+...
+* Connection #0 to host 0.0.0.0 left intact
+```
+
+
+[Backend]: ../../../api/extension_types#backend
diff --git a/site/content/en/v1.2/tasks/quickstart.md b/site/content/en/v1.2/tasks/quickstart.md
new file mode 100644
index 00000000000..e1943c21e92
--- /dev/null
+++ b/site/content/en/v1.2/tasks/quickstart.md
@@ -0,0 +1,130 @@
+---
+title: "Quickstart"
+weight: 1
+description: Get started with Envoy Gateway in a few simple steps.
+---
+
+This "quick start" will help you get started with Envoy Gateway in a few simple steps.
+
+## Prerequisites
+
+A Kubernetes cluster.
+
+__Note:__ Refer to the [Compatibility Matrix](/news/releases/matrix) for supported Kubernetes versions.
+
+__Note:__ In case your Kubernetes cluster does not have a LoadBalancer implementation, we recommend installing one
+so the `Gateway` resource has an Address associated with it. We recommend using [MetalLB](https://metallb.universe.tf/installation/).
+
+__Note:__ For Mac user, you need install and run [Docker Mac Net Connect](https://github.com/chipmk/docker-mac-net-connect) to make the Docker network work.
+
+## Installation
+
+Install the Gateway API CRDs and Envoy Gateway:
+
+```shell
+helm install eg oci://docker.io/envoyproxy/gateway-helm --version {{< helm-version >}} -n envoy-gateway-system --create-namespace
+```
+
+Wait for Envoy Gateway to become available:
+
+```shell
+kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
+```
+
+Install the GatewayClass, Gateway, HTTPRoute and example app:
+
+```shell
+kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/{{< yaml-version >}}/quickstart.yaml -n default
+```
+
+**Note**: [`quickstart.yaml`] defines that Envoy Gateway will listen for
+traffic on port 80 on its globally-routable IP address, to make it easy to use
+browsers to test Envoy Gateway. When Envoy Gateway sees that its Listener is
+using a privileged port (<1024), it will map this internally to an
+unprivileged port, so that Envoy Gateway doesn't need additional privileges.
+It's important to be aware of this mapping, since you may need to take it into
+consideration when debugging.
+
+[`quickstart.yaml`]: https://github.com/envoyproxy/gateway/releases/download/{{< yaml-version >}}/quickstart.yaml
+
+## Testing the Configuration
+
+{{< tabpane text=true >}}
+{{% tab header="With External LoadBalancer Support" %}}
+
+You can also test the same functionality by sending traffic to the External IP. To get the external IP of the
+Envoy service, run:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+In certain environments, the load balancer may be exposed using a hostname, instead of an IP address. If so, replace
+`ip` in the above command with `hostname`.
+
+Curl the example app through Envoy proxy:
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get
+```
+
+{{% /tab %}}
+{{% tab header="Without LoadBalancer Support" %}}
+
+Get the name of the Envoy service created the by the example Gateway:
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+```
+
+Port forward to the Envoy service:
+
+```shell
+kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8888:80 &
+```
+
+Curl the example app through Envoy proxy:
+
+```shell
+curl --verbose --header "Host: www.example.com" http://localhost:8888/get
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+## What to explore next?
+
+In this quickstart, you have:
+- Installed Envoy Gateway
+- Deployed a backend service, and a gateway
+- Configured the gateway using Kubernetes Gateway API resources [Gateway](https://gateway-api.sigs.k8s.io/api-types/gateway/) and [HttpRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/) to direct incoming requests over HTTP to the backend service.
+
+Here is a suggested list of follow-on tasks to guide you in your exploration of Envoy Gateway:
+
+- [HTTP Routing](traffic/http-routing)
+- [Traffic Splitting](traffic/http-traffic-splitting)
+- [Secure Gateways](security/secure-gateways/)
+- [Global Rate Limit](traffic/global-rate-limit/)
+- [gRPC Routing](traffic/grpc-routing/)
+
+Review the [Tasks](./) section for the scenario matching your use case. The Envoy Gateway tasks are organized by category: traffic management, security, extensibility, observability, and operations.
+
+## Clean-Up
+
+Use the steps in this section to uninstall everything from the quickstart.
+
+Delete the GatewayClass, Gateway, HTTPRoute and Example App:
+
+```shell
+kubectl delete -f https://github.com/envoyproxy/gateway/releases/download/{{< yaml-version >}}/quickstart.yaml --ignore-not-found=true
+```
+
+Delete the Gateway API CRDs and Envoy Gateway:
+
+```shell
+helm uninstall eg -n envoy-gateway-system
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../contributions/develop) to get involved in the project.
diff --git a/site/content/en/v1.2/tasks/security/_index.md b/site/content/en/v1.2/tasks/security/_index.md
new file mode 100644
index 00000000000..0e6a64144a7
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Security"
+weight: 2
+description: This section includes Security tasks.
+---
diff --git a/site/content/en/v1.2/tasks/security/backend-mtls.md b/site/content/en/v1.2/tasks/security/backend-mtls.md
new file mode 100644
index 00000000000..1d91c7a95f8
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/backend-mtls.md
@@ -0,0 +1,200 @@
+---
+title: "Backend Mutual TLS: Gateway to Backend"
+---
+
+This task demonstrates how mTLS can be achieved between the Gateway and a backend.
+This task uses a self-signed CA, so it should be used for testing and demonstration purposes only.
+
+Envoy Gateway supports the Gateway-API defined [BackendTLSPolicy][] to establish TLS. For mTLS, the Gateway must authenticate by presenting a client certificate to the backend.
+
+## Prerequisites
+
+- OpenSSL to generate TLS assets.
+
+## Installation
+
+Follow the steps from the [Backend TLS][] to install Envoy Gateway and configure TLS to the backend server.
+
+## TLS Certificates
+
+Generate the certificates and keys used by the Gateway for authentication against the backend.
+
+Create a root certificate and private key to sign certificates:
+
+```shell
+openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout clientca.key -out clientca.crt
+```
+
+Create a certificate and a private key for `www.example.com`:
+
+```shell
+openssl req -new -newkey rsa:2048 -nodes -keyout client.key -out client.csr -subj "/CN=example-client/O=example organization"
+openssl x509 -req -days 365 -CA clientca.crt -CAkey clientca.key -set_serial 0 -in client.csr -out client.crt
+```
+
+Store the cert/key in a Secret:
+
+```shell
+kubectl -n envoy-gateway-system create secret tls example-client-cert --key=client.key --cert=client.crt
+```
+
+Store the CA Cert in another Secret:
+
+```shell
+kubectl create configmap example-client-ca --from-file=clientca.crt
+```
+
+## Enforce Client Certificate Authentication on the backend
+
+Patch the existing quickstart backend to enforce Client Certificate Authentication. The patch will mount the server certificate and key required for TLS, and the CA certificate into the backend as volumes.
+
+```shell
+kubectl patch deployment backend --type=json --patch '
+ - op: add
+ path: /spec/template/spec/containers/0/volumeMounts
+ value:
+ - name: client-certs-volume
+ mountPath: /etc/client-certs
+ - name: secret-volume
+ mountPath: /etc/secret-volume
+ - op: add
+ path: /spec/template/spec/volumes
+ value:
+ - name: client-certs-volume
+ configMap:
+ name: example-client-ca
+ items:
+ - key: clientca.crt
+ path: crt
+ - name: secret-volume
+ secret:
+ secretName: example-cert
+ items:
+ - key: tls.crt
+ path: crt
+ - key: tls.key
+ path: key
+ - op: add
+ path: /spec/template/spec/containers/0/env/-
+ value:
+ name: TLS_CLIENT_CACERTS
+ value: /etc/client-certs/crt
+ '
+```
+
+## Configure Envoy Proxy to use a client certificate
+
+In addition to enablement of backend TLS with the Gateway-API BackendTLSPolicy, Envoy Gateway supports customizing TLS parameters such as TLS Client Certificate.
+To achieve this, the [EnvoyProxy][] resource can be used to specify a TLS Client Certificate.
+
+First, you need to add ParametersRef in GatewayClass, and refer to EnvoyProxy Config:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+## Testing mTLS
+
+Query the TLS-enabled backend through Envoy proxy:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:80:127.0.0.1" \
+http://www.example.com:80/get
+```
+
+Inspect the output and see that the response contains the details of the TLS handshake between Envoy and the backend.
+The response now contains a "peerCertificates" attribute that reflects the client certificate used by the Gateway to establish mTLS with the backend.
+
+```shell
+< HTTP/1.1 200 OK
+[...]
+ "tls": {
+ "version": "TLSv1.2",
+ "serverName": "www.example.com",
+ "negotiatedProtocol": "http/1.1",
+ "cipherSuite": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
+ "peerCertificates": ["-----BEGIN CERTIFICATE-----\n[...]-----END CERTIFICATE-----\n"]
+ }
+```
+
+[Backend TLS]: ./backend-tls
+[BackendTLSPolicy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
+[EnvoyProxy]: ../../api/extension_types#envoyproxy
\ No newline at end of file
diff --git a/site/content/en/v1.2/tasks/security/backend-tls.md b/site/content/en/v1.2/tasks/security/backend-tls.md
new file mode 100644
index 00000000000..945a1f5ff98
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/backend-tls.md
@@ -0,0 +1,412 @@
+---
+title: "Backend TLS: Gateway to Backend"
+---
+
+This task demonstrates how TLS can be achieved between the Gateway and a backend.
+This task uses a self-signed CA, so it should be used for testing and demonstration purposes only.
+
+Envoy Gateway supports the Gateway-API defined [BackendTLSPolicy][].
+
+## Prerequisites
+
+- OpenSSL to generate TLS assets.
+
+## Installation
+
+{{< boilerplate prerequisites >}}
+
+## TLS Certificates
+
+Generate the certificates and keys used by the backend to terminate TLS connections from the Gateways.
+
+Create a root certificate and private key to sign certificates:
+
+```shell
+openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout ca.key -out ca.crt
+```
+
+Create a certificate and a private key for `www.example.com`.
+
+First, create an openssl configuration file:
+
+```shell
+cat > openssl.conf <}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Create a [BackendTLSPolicy][] instructing Envoy Gateway to establish a TLS connection with the backend and validate the backend certificate is issued by a trusted CA and contains an appropriate DNS SAN.
+
+Note: SectionName is an optional field that specifies the name of the port in the target backend. This example uses a Kubernetes Service as the backend target, so the sectionName is set to `https` to match the port name in the Service.
+If the target is a [Backend] resource, the `sectionName` field should be set to the port number of the backend.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Patch the HTTPRoute's backend reference, so that it refers to the new TLS-enabled service:
+
+```shell
+kubectl patch HTTPRoute backend --type=json --patch '
+ - op: replace
+ path: /spec/rules/0/backendRefs/0/port
+ value: 443
+ - op: replace
+ path: /spec/rules/0/backendRefs/0/name
+ value: tls-backend
+ '
+```
+
+Verify the HTTPRoute status:
+
+```shell
+kubectl get HTTPRoute backend -o yaml
+```
+
+## Testing backend TLS
+
+{{< tabpane text=true >}}
+{{% tab header="With External LoadBalancer Support" %}}
+
+Get the External IP of the Gateway:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+Query the example app through the Gateway:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:80:${GATEWAY_HOST}" \
+http://www.example.com:80/get
+```
+
+Inspect the output and see that the response contains the details of the TLS handshake between Envoy and the backend:
+
+```shell
+< HTTP/1.1 200 OK
+[...]
+ "tls": {
+ "version": "TLSv1.2",
+ "serverName": "www.example.com",
+ "negotiatedProtocol": "http/1.1",
+ "cipherSuite": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
+ }
+```
+
+{{% /tab %}}
+{{% tab header="Without LoadBalancer Support" %}}
+
+Get the name of the Envoy service created the by the example Gateway:
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+```
+
+Port forward to the Envoy service:
+
+```shell
+kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 80:80 &
+```
+
+Query the TLS-enabled backend through Envoy proxy:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:80:127.0.0.1" \
+http://www.example.com:80/get
+```
+
+Inspect the output and see that the response contains the details of the TLS handshake between Envoy and the backend:
+
+```shell
+< HTTP/1.1 200 OK
+[...]
+ "tls": {
+ "version": "TLSv1.2",
+ "serverName": "www.example.com",
+ "negotiatedProtocol": "http/1.1",
+ "cipherSuite": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
+ }
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+## Customize backend TLS Parameters
+
+In addition to enablement of backend TLS with the Gateway-API BackendTLSPolicy, Envoy Gateway supports customizing TLS parameters.
+To achieve this, the [EnvoyProxy][] resource can be used to specify TLS parameters. We will customize the TLS version in this example.
+
+First, you need to add ParametersRef in GatewayClass, and refer to EnvoyProxy Config:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+You can customize the EnvoyProxy Backend TLS Parameters via EnvoyProxy Config like:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+## Testing TLS Parameters
+
+Query the TLS-enabled backend through Envoy proxy:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:80:127.0.0.1" \
+http://www.example.com:80/get
+```
+
+Inspect the output and see that the response contains the details of the TLS handshake between Envoy and the backend.
+The TLS version is now TLS1.3, as configured in the EnvoyProxy resource. The TLS cipher is also changed, since TLS1.3 supports different ciphers from TLS1.2.
+
+```shell
+< HTTP/1.1 200 OK
+[...]
+ "tls": {
+ "version": "TLSv1.3",
+ "serverName": "www.example.com",
+ "negotiatedProtocol": "http/1.1",
+ "cipherSuite": "TLS_AES_128_GCM_SHA256"
+ }
+```
+
+[BackendTLSPolicy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
+[EnvoyProxy]: ../../api/extension_types#envoyproxy
+[Backend]: ../../api/extension_types#backend
diff --git a/site/content/en/v1.2/tasks/security/basic-auth.md b/site/content/en/v1.2/tasks/security/basic-auth.md
new file mode 100644
index 00000000000..cc0ec54ada1
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/basic-auth.md
@@ -0,0 +1,219 @@
+---
+title: "Basic Authentication"
+---
+
+This task provides instructions for configuring [HTTP Basic authentication][http Basic authentication].
+HTTP Basic authentication checks if an incoming request has a valid username and password before routing the request to
+a backend service.
+
+Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure HTTP Basic
+authentication.
+This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HTTPRoute] or [GRPCRoute][GRPCRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## Configuration
+
+Envoy Gateway uses [.htpasswd][.htpasswd] format to store the username-password pairs for authentication.
+The file must be stored in a kubernetes secret and referenced in the [SecurityPolicy][SecurityPolicy] configuration.
+The secret is an Opaque secret, and the username-password pairs must be stored in the key ".htpasswd".
+
+### Create a root certificate
+
+Create a root certificate and private key to sign certificates:
+
+```shell
+openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
+```
+
+### Create a certificate secret
+
+Create a certificate and a private key for `www.example.com`:
+
+```shell
+openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization"
+openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt
+```
+
+### Create certificate
+
+```shell
+kubectl create secret tls example-cert --key=www.example.com.key --cert=www.example.com.crt
+```
+
+### Enable HTTPS
+Update the Gateway from the Quickstart to include an HTTPS listener that listens on port `443` and references the
+`example-cert` Secret:
+
+```shell
+kubectl patch gateway eg --type=json --patch '
+ - op: add
+ path: /spec/listeners/-
+ value:
+ name: https
+ protocol: HTTPS
+ port: 443
+ tls:
+ mode: Terminate
+ certificateRefs:
+ - kind: Secret
+ group: ""
+ name: example-cert
+ '
+```
+
+### Create a .htpasswd file
+First, create a [.htpasswd][.htpasswd] file with the username and password you want to use for authentication.
+
+Note: Please always use HTTPS with Basic Authentication. This prevents credentials from being transmitted in plain text.
+
+The input password won't be saved, instead, a hash will be generated and saved in the output file. When a request
+tries to access protected resources, the password in the "Authorization" HTTP header will be hashed and compared with the
+saved hash.
+
+Note: only SHA hash algorithm is supported for now.
+
+```shell
+htpasswd -cbs .htpasswd foo bar
+```
+
+You can also add more users to the file:
+
+```shell
+htpasswd -bs .htpasswd foo1 bar1
+```
+
+### Create a basic-auth secret
+
+
+Next, create a kubernetes secret with the generated .htpasswd file in the previous step.
+
+```shell
+kubectl create secret generic basic-auth --from-file=.htpasswd
+```
+
+### Create a SecurityPolicy
+
+The below example defines a SecurityPolicy that authenticates requests against the user list in the kubernetes
+secret generated in the previous step.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/basic-auth-example -o yaml
+```
+
+## Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+Send a request to the backend service without `Authentication` header:
+
+```shell
+curl -kv -H "Host: www.example.com" "https://${GATEWAY_HOST}/"
+```
+
+You should see `401 Unauthorized` in the response, indicating that the request is not allowed without authentication.
+
+```shell
+* Connected to 127.0.0.1 (127.0.0.1) port 443
+...
+* Server certificate:
+* subject: CN=www.example.com; O=example organization
+* issuer: O=example Inc.; CN=example.com
+> GET / HTTP/2
+> Host: www.example.com
+> User-Agent: curl/8.6.0
+> Accept: */*
+...
+< HTTP/2 401
+< content-length: 58
+< content-type: text/plain
+< date: Wed, 06 Mar 2024 15:59:36 GMT
+<
+
+* Connection #0 to host 127.0.0.1 left intact
+User authentication failed. Missing username and password.
+```
+
+Send a request to the backend service with `Authentication` header:
+
+```shell
+curl -kv -H "Host: www.example.com" -u 'foo:bar' "https://${GATEWAY_HOST}/"
+```
+
+The request should be allowed and you should see the response from the backend service.
+
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the SecurityPolicy and the secret
+
+```shell
+kubectl delete securitypolicy/basic-auth-example
+kubectl delete secret/basic-auth
+kubectl delete secret/example-cert
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[SecurityPolicy]: ../../../contributions/design/security-policy
+[http Basic authentication]: https://tools.ietf.org/html/rfc2617
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[GRPCRoute]: https://gateway-api.sigs.k8s.io/api-types/grpcroute
+[.htpasswd]: https://httpd.apache.org/docs/current/programs/htpasswd.html
diff --git a/site/content/en/v1.2/tasks/security/cors.md b/site/content/en/v1.2/tasks/security/cors.md
new file mode 100644
index 00000000000..90a972ce4ca
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/cors.md
@@ -0,0 +1,176 @@
+---
+title: "CORS"
+---
+
+This task provides instructions for configuring [Cross-Origin Resource Sharing (CORS)][cors] on Envoy Gateway.
+CORS defines a way for client web applications that are loaded in one domain to interact with resources in a different
+domain.
+
+Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure CORS.
+This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HTTPRoute] or [GRPCRoute][GRPCRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## Configuration
+
+When configuring CORS either an origin with a precise hostname can be configured or an hostname containing a wildcard prefix,
+allowing all subdomains of the specified hostname.
+In addition to that the entire origin (with or without specifying a scheme) can be a wildcard to allow all origins.
+
+The below example defines a SecurityPolicy that allows CORS for all HTTP requests originating from `www.foo.com`.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/cors-example -o yaml
+```
+
+## Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+Verify that the CORS headers are present in the response of the OPTIONS request from `http://www.foo.com`:
+
+```shell
+curl -H "Origin: http://www.foo.com" \
+ -H "Host: www.example.com" \
+ -H "Access-Control-Request-Method: GET" \
+ -X OPTIONS -v -s \
+ http://$GATEWAY_HOST \
+ 1> /dev/null
+```
+
+You should see the below response, indicating that the request from `http://www.foo.com` is allowed:
+
+```shell
+< access-control-allow-origin: http://www.foo.com
+< access-control-allow-methods: GET, POST
+< access-control-allow-headers: x-header-1, x-header-2
+< access-control-max-age: 86400
+< access-control-expose-headers: x-header-3, x-header-4
+```
+
+If you try to send a request from `http://www.bar.com`, you should see the below response:
+
+```shell
+curl -H "Origin: http://www.bar.com" \
+ -H "Host: www.example.com" \
+ -H "Access-Control-Request-Method: GET" \
+ -X OPTIONS -v -s \
+ http://$GATEWAY_HOST \
+ 1> /dev/null
+```
+
+You won't see any CORS headers in the response, indicating that the request from `http://www.bar.com` was not allowed.
+
+If you try to send a request from `http://www.foo.com:8080`, you should also see similar response because the port number
+`8080` is not included in the allowed origins.
+
+```shell
+```shell
+curl -H "Origin: http://www.foo.com:8080" \
+ -H "Host: www.example.com" \
+ -H "Access-Control-Request-Method: GET" \
+ -X OPTIONS -v -s \
+ http://$GATEWAY_HOST \
+ 1> /dev/null
+```
+
+Note:
+* CORS specification requires that the browsers to send a preflight request to the server to ask if it's allowed
+to access the limited resource in another domains. The browsers are supposed to follow the response from the server to
+determine whether to send the actual request or not. The CORS filter only response to the preflight requests according to
+its configuration. It won't deny any requests. The browsers are responsible for enforcing the CORS policy.
+* The targeted HTTPRoute or the HTTPRoutes that the targeted Gateway routes to must allow the OPTIONS method for the CORS
+filter to work. Otherwise, the OPTIONS request won't match the routes and the CORS filter won't be invoked.
+
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the SecurityPolicy:
+
+```shell
+kubectl delete securitypolicy/cors-example
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[SecurityPolicy]: ../../../contributions/design/security-policy
+[cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[GRPCRoute]: https://gateway-api.sigs.k8s.io/api-types/grpcroute
diff --git a/site/content/en/v1.2/tasks/security/ext-auth.md b/site/content/en/v1.2/tasks/security/ext-auth.md
new file mode 100644
index 00000000000..1d1625d5780
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/ext-auth.md
@@ -0,0 +1,453 @@
+---
+title: "External Authorization"
+---
+
+This task provides instructions for configuring external authentication.
+
+External authorization calls an external HTTP or gRPC service to check whether an incoming HTTP request is authorized
+or not. If the request is deemed unauthorized, then the request will be denied with a 403 (Forbidden) response. If the
+request is authorized, then the request will be allowed to proceed to the backend service.
+
+Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure external authorization.
+This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute][HTTPRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## HTTP External Authorization Service
+
+### Installation
+
+Install a demo HTTP service that will be used as the external authorization service:
+
+```shell
+kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/ext-auth-http-service.yaml
+```
+
+Create a new HTTPRoute resource to route traffic on the path `/myapp` to the backend service.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the HTTPRoute status:
+
+```shell
+kubectl get httproute/myapp -o yaml
+```
+
+### Configuration
+
+Create a new SecurityPolicy resource to configure the external authorization. This SecurityPolicy targets the HTTPRoute
+"myApp" created in the previous step. It calls the HTTP external authorization service "http-ext-auth" on port 9002 for
+authorization. The `headersToBackend` field specifies the headers that will be sent to the backend service if the request
+is successfully authorized.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/ext-auth-example -o yaml
+```
+
+### Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+Send a request to the backend service without `Authentication` header:
+
+```shell
+curl -v -H "Host: www.example.com" "http://${GATEWAY_HOST}/myapp"
+```
+
+You should see `403 Forbidden` in the response, indicating that the request is not allowed without authentication.
+
+```shell
+* Connected to 172.18.255.200 (172.18.255.200) port 80 (#0)
+> GET /myapp HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/7.68.0
+> Accept: */*
+...
+< HTTP/1.1 403 Forbidden
+< date: Mon, 11 Mar 2024 03:41:15 GMT
+< x-envoy-upstream-service-time: 0
+< content-length: 0
+<
+* Connection #0 to host 172.18.255.200 left intact
+```
+
+Send a request to the backend service with `Authentication` header:
+
+```shell
+curl -v -H "Host: www.example.com" -H "Authorization: Bearer token1" "http://${GATEWAY_HOST}/myapp"
+```
+
+The request should be allowed and you should see the response from the backend service.
+Because the `x-current-user` header from the auth response has been sent to the backend service,
+you should see the `x-current-user` header in the response.
+
+```
+"X-Current-User": [
+ "user1"
+ ],
+```
+
+## GRPC External Authorization Service
+
+### Installation
+
+Install a demo gRPC service that will be used as the external authorization service. The demo gRPC service is enabled
+with TLS and a BackendTLSConfig is created to configure the communication between the Envoy proxy and the gRPC service.
+
+Note: TLS is optional for HTTP or gRPC external authorization services. However, enabling TLS is recommended for enhanced
+security in production environments.
+
+```shell
+kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/ext-auth-grpc-service.yaml
+```
+
+The HTTPRoute created in the previous section is still valid and can be used with the gRPC auth service, but if you have
+not created the HTTPRoute, you can create it now.
+
+Create a new HTTPRoute resource to route traffic on the path `/myapp` to the backend service.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the HTTPRoute status:
+
+```shell
+kubectl get httproute/myapp -o yaml
+```
+
+### Configuration
+
+Update the SecurityPolicy that was created in the previous section to use the gRPC external authorization service.
+It calls the gRPC external authorization service "grpc-ext-auth" on port 9002 for authorization.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/ext-auth-example -o yaml
+```
+
+Because the gRPC external authorization service is enabled with TLS, a BackendTLSConfig needs to be created to configure
+the communication between the Envoy proxy and the gRPC auth service.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the BackendTLSPolicy configuration:
+
+```shell
+kubectl get backendtlspolicy/grpc-ext-auth-btls -o yaml
+```
+
+### Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+Send a request to the backend service without `Authentication` header:
+
+```shell
+curl -v -H "Host: www.example.com" "http://${GATEWAY_HOST}/myapp"
+```
+
+You should see `403 Forbidden` in the response, indicating that the request is not allowed without authentication.
+
+```shell
+* Connected to 172.18.255.200 (172.18.255.200) port 80 (#0)
+> GET /myapp HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/7.68.0
+> Accept: */*
+...
+< HTTP/1.1 403 Forbidden
+< date: Mon, 11 Mar 2024 03:41:15 GMT
+< x-envoy-upstream-service-time: 0
+< content-length: 0
+<
+* Connection #0 to host 172.18.255.200 left intact
+```
+
+Send a request to the backend service with `Authentication` header:
+
+```shell
+curl -v -H "Host: www.example.com" -H "Authorization: Bearer token1" "http://${GATEWAY_HOST}/myapp"
+```
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the demo auth services, HTTPRoute, SecurityPolicy and BackendTLSPolicy:
+
+```shell
+kubectl delete -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/ext-auth-http-service.yaml
+kubectl delete -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/ext-auth-grpc-service.yaml
+kubectl delete httproute/myapp
+kubectl delete securitypolicy/ext-auth-example
+kubectl delete backendtlspolicy/grpc-ext-auth-btls
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[SecurityPolicy]: ../../../contributions/design/security-policy
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
diff --git a/site/content/en/v1.2/tasks/security/jwt-authentication.md b/site/content/en/v1.2/tasks/security/jwt-authentication.md
new file mode 100644
index 00000000000..e4361b6354f
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/jwt-authentication.md
@@ -0,0 +1,170 @@
+---
+title: "JWT Authentication"
+---
+
+This task provides instructions for configuring [JSON Web Token (JWT)][jwt] authentication. JWT authentication checks
+if an incoming request has a valid JWT before routing the request to a backend service. Currently, Envoy Gateway only
+supports validating a JWT from an HTTP header, e.g. `Authorization: Bearer `.
+
+Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure JWT authentication.
+This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HTTPRoute] or [GRPCRoute][GRPCRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+For GRPC - follow the steps from the [GRPC Routing](../traffic/grpc-routing) example.
+
+## Configuration
+
+Allow requests with a valid JWT by creating an [SecurityPolicy][SecurityPolicy] and attaching it to the example
+HTTPRoute or GRPCRoute.
+
+### HTTPRoute
+
+```shell
+kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/jwt/jwt.yaml
+```
+
+Two HTTPRoute has been created, one for `/foo` and another for `/bar`. A SecurityPolicy has been created and targeted
+HTTPRoute foo to authenticate requests for `/foo`. The HTTPRoute bar is not targeted by the SecurityPolicy and will allow
+unauthenticated requests to `/bar`.
+
+Verify the HTTPRoute configuration and status:
+
+```shell
+kubectl get httproute/foo -o yaml
+kubectl get httproute/bar -o yaml
+```
+
+The SecurityPolicy is configured for JWT authentication and uses a single [JSON Web Key Set (JWKS)][jwks]
+provider for authenticating the JWT.
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/jwt-example -o yaml
+```
+
+### GRPCRoute
+
+```shell
+kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/jwt/grpc-jwt.yaml
+```
+
+A SecurityPolicy has been created and targeted GRPCRoute yages to authenticate all requests for `yages` service..
+
+Verify the GRPCRoute configuration and status:
+
+```shell
+kubectl get grpcroute/yages -o yaml
+```
+
+The SecurityPolicy is configured for JWT authentication and uses a single [JSON Web Key Set (JWKS)][jwks]
+provider for authenticating the JWT.
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/jwt-example -o yaml
+```
+
+## Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+### HTTPRoute
+
+Verify that requests to `/foo` are denied without a JWT:
+
+```shell
+curl -sS -o /dev/null -H "Host: www.example.com" -w "%{http_code}\n" http://$GATEWAY_HOST/foo
+```
+
+A `401` HTTP response code should be returned.
+
+Get the JWT used for testing request authentication:
+
+```shell
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
+```
+
+__Note:__ The above command decodes and returns the token's payload. You can replace `f2` with `f1` to view the token's
+header.
+
+Verify that a request to `/foo` with a valid JWT is allowed:
+
+```shell
+curl -sS -o /dev/null -H "Host: www.example.com" -H "Authorization: Bearer $TOKEN" -w "%{http_code}\n" http://$GATEWAY_HOST/foo
+```
+
+A `200` HTTP response code should be returned.
+
+Verify that requests to `/bar` are allowed __without__ a JWT:
+
+```shell
+curl -sS -o /dev/null -H "Host: www.example.com" -w "%{http_code}\n" http://$GATEWAY_HOST/bar
+```
+
+### GRPCRoute
+
+Verify that requests to `yages`service are denied without a JWT:
+
+```shell
+grpcurl -plaintext -authority=grpc-example.com ${GATEWAY_HOST}:80 yages.Echo/Ping
+```
+
+You should see the below response
+
+```shell
+Error invoking method "yages.Echo/Ping": rpc error: code = Unauthenticated desc = failed to query for service descriptor "yages.Echo": Jwt is missing
+```
+
+Get the JWT used for testing request authentication:
+
+```shell
+TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
+```
+
+__Note:__ The above command decodes and returns the token's payload. You can replace `f2` with `f1` to view the token's
+header.
+
+Verify that a request to `yages` service with a valid JWT is allowed:
+
+```shell
+grpcurl -plaintext -H "authorization: Bearer $TOKEN" -authority=grpc-example.com ${GATEWAY_HOST}:80 yages.Echo/Ping
+```
+
+You should see the below response
+
+```shell
+{
+ "text": "pong"
+}
+```
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the SecurityPolicy:
+
+```shell
+kubectl delete securitypolicy/jwt-example
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[SecurityPolicy]: ../../../contributions/design/security-policy
+[jwt]: https://tools.ietf.org/html/rfc7519
+[jwks]: https://tools.ietf.org/html/rfc7517
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[GRPCRoute]: https://gateway-api.sigs.k8s.io/api-types/grpcroute
diff --git a/site/content/en/v1.2/tasks/security/jwt-claim-authorization.md b/site/content/en/v1.2/tasks/security/jwt-claim-authorization.md
new file mode 100644
index 00000000000..2e67ea7ffe9
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/jwt-claim-authorization.md
@@ -0,0 +1,226 @@
+---
+title: "JWT Claim-Based Authorization"
+---
+
+This task provides instructions for configuring JWT claim-based authorization. JWT claim-based authorization checks if an incoming request has the required JWT claims before routing the request to a backend service.
+
+Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure JWT claim-based authorization.
+
+This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HTTPRoute] or [GRPCRoute][GRPCRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## Configuration
+
+### Create a SecurityPolicy
+
+Please note that the JWT claim-based authorization requires the JWT token to be present in the request. A JWT authentication must be configured in the same SecurityPolicy to validate the JWT token and extract the claims.
+
+The below SecurityPolicy configuration allows requests with a valid JWT token that has the following claims:
+- `user.name` claim with the value `John Doe`
+- `user.roles` claim with the value `admin`
+- `scope` claim with the values `read`, `add`, and `modify`
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/authorization-jwt-claim -o yaml
+```
+
+## Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+Define a JWT token with the required claims.
+
+```shell
+export VALID_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImI1MjBiM2MyYzRiZDc1YTEwZTljZWJjOTU3NjkzM2RjIn0.eyJpc3MiOiJodHRwczovL2Zvby5iYXIuY29tIiwic3ViIjoiMTIzNDU2Nzg5MCIsInVzZXIiOnsibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqb2huLmRvZUBleGFtcGxlLmNvbSIsInJvbGVzIjpbImFkbWluIiwiZWRpdG9yIl19LCJwcmVtaXVtX3VzZXIiOnRydWUsImlhdCI6MTUxNjIzOTAyMiwic2NvcGUiOiJyZWFkIGFkZCBkZWxldGUgbW9kaWZ5In0.P36iAlmiRCC79OiB3vstF5Q_9OqUYAMGF3a3H492GlojbV6DcuOz8YIEYGsRSWc-BNJaBKlyvUKsKsGVPtYbbF8ajwZTs64wyO-zhd2R8riPkg_HsW7iwGswV12f5iVRpfQ4AG2owmdOToIaoch0aym89He1ZzEjcShr9olgqlAbbmhnk-namd1rP-xpzPnWhhIVI3mCz5hYYgDTMcM7qbokM5FzFttTRXAn5_Luor23U1062Ct_K53QArwxBvwJ-QYiqcBycHf-hh6sMx_941cUswrZucCpa-EwA3piATf9PKAyeeWHfHV9X-y8ipGOFg3mYMMVBuUZ1lBkJCik9f9kboRY6QzpOISARQj9PKMXfxZdIPNuGmA7msSNAXQgqkvbx04jMwb9U7eCEdGZztH4C8LhlRjgj0ZdD7eNbRjeH2F6zrWyMUpGWaWyq6rMuP98W2DWM5ZflK6qvT1c7FuFsWPvWLkgxQwTWQKrHdKwdbsu32Sj8VtUBJ0-ddEb"
+```
+
+Decode the JWT token to verify that it has the required claims.
+
+```shell
+jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< $(echo ${VALID_TOKEN})
+```
+
+The decoded JWT token should look like the following:
+
+```json
+{
+ "typ": "JWT",
+ "alg": "RS256",
+ "kid": "b520b3c2c4bd75a10e9cebc9576933dc"
+}
+{
+ "iss": "https://foo.bar.com",
+ "sub": "1234567890",
+ "user": {
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "roles": [
+ "admin",
+ "editor"
+ ]
+ },
+ "premium_user": true,
+ "iat": 1516239022,
+ "scope": "read add delete modify"
+}
+```
+
+Send a request to the backend service with the valid JWT token:
+
+```shell
+curl -H "Host: www.example.com" -H "Authorization: Bearer ${VALID_TOKEN}" "http://${GATEWAY_HOST}/"
+```
+
+The request should be allowed and you should see the response from the backend service.
+
+Define a JWT token without the required claims.
+
+```shell
+export INVALID_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImI1MjBiM2MyYzRiZDc1YTEwZTljZWJjOTU3NjkzM2RjIn0.eyJpc3MiOiJodHRwczovL2Zvby5iYXIuY29tIiwic3ViIjoiMTIzNDU2Nzg5MCIsInVzZXIiOnsibmFtZSI6IkFsaWNlIFNtaXRoIiwiZW1haWwiOiJhbGljZS5zbWl0aEBleGFtcGxlLmNvbSIsInJvbGVzIjpbImRldmVsb3BlciJdfSwicHJlbWl1bV91c2VyIjpmYWxzZSwiaWF0IjoxNTE2MjM5MDIyLCJzY29wZSI6InJlYWQgYWRkIGRlbGV0ZSJ9.Da547nNXzuQXm5E7LuLAiyFswXsW4RDhuitD_rpadtR7PTwzzOsJoqrVWJ_u1jJDaOTWIpLF4gwxDoY-Aoz_couzXzlAbECLs45ZFoc_UdffpfIbGKqTZx8VtwKuDLFsAeDDDqqx1flxFhvXHftJJdZYr1FgFz9u-absMmRU90DLmEZX3Hnyc8k8eBgeiu6vsWUD0-aNy8cWkFRbwRggkGmucFyUTG8Z1MY3iyH5E66W-ISoX8G9bzE9PTxVAAPDTvefD5iLJPSDJ8qV69OuMCJ8Dczq0L9Dd_w0sF-D1s9MTvexmGg4zBWluJ3r-pU9NHEdhqBypehp_yH8xF5Rt9AE7stZ4oPFZNyfrtkE-4IOnSEkMmzcC65g_rscn0ycerv4N5ZNpkr0x2IYYM4iGuo-ULv5Htnli3rffST45kx1XA8cdsrT1D0K3aPxdIxDIk8sTJf5-WVqRyo-bwxXXltwQLB9jCM_7QbTWQBYAJwUpi-0RW4jCl44-42gZnXf"
+```
+
+Decode the JWT token to verify that it does not have the required claims.
+
+```shell
+jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< $(echo ${INVALID_TOKEN})
+```
+
+The decoded JWT token should look like the following:
+
+```json
+{
+ "typ": "JWT",
+ "alg": "RS256",
+ "kid": "b520b3c2c4bd75a10e9cebc9576933dc"
+}
+{
+ "iss": "https://foo.bar.com",
+ "sub": "1234567890",
+ "user": {
+ "name": "Alice Smith",
+ "email": "alice.smith@example.com",
+ "roles": [
+ "developer"
+ ]
+ },
+ "premium_user": false,
+ "iat": 1516239022,
+ "scope": "read add delete"
+}
+```
+
+Send a request to the backend service with the invalid JWT token:
+
+```shell
+curl -v -H "Host: www.example.com" -H "Authorization: Bearer ${INVALID_TOKEN}" "http://${GATEWAY_HOST}/"
+```
+
+The request should be denied and you should see a `403 Forbidden` response.
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the SecurityPolicy and the ClientTrafficPolicy
+
+```shell
+kubectl delete securitypolicy/authorization-jwt-claim
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[SecurityPolicy]: ../../../contributions/design/security-policy
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[GRPCRoute]: https://gateway-api.sigs.k8s.io/api-types/grpcroute
diff --git a/site/content/en/v1.2/tasks/security/mutual-tls.md b/site/content/en/v1.2/tasks/security/mutual-tls.md
new file mode 100644
index 00000000000..4ac9f96430a
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/mutual-tls.md
@@ -0,0 +1,183 @@
+---
+title: "Mutual TLS: External Clients to the Gateway"
+---
+
+This task demonstrates how mutual TLS can be achieved between external clients and the Gateway.
+This task uses a self-signed CA, so it should be used for testing and demonstration purposes only.
+
+## Prerequisites
+
+- OpenSSL to generate TLS assets.
+
+## Installation
+
+{{< boilerplate prerequisites >}}
+
+## TLS Certificates
+
+Generate the certificates and keys used by the Gateway to terminate client TLS connections.
+
+Create a root certificate and private key to sign certificates:
+
+```shell
+openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
+```
+
+Create a certificate and a private key for `www.example.com`:
+
+```shell
+openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization"
+openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt
+```
+
+Store the cert/key in a Secret:
+
+```shell
+kubectl create secret tls example-cert --key=www.example.com.key --cert=www.example.com.crt --certificate-authority=example.com.crt
+```
+
+Store the CA Cert in another Secret:
+
+```shell
+kubectl create secret generic example-ca-cert --from-file=ca.crt=example.com.crt
+```
+
+Create a certificate and a private key for the client `client.example.com`:
+
+```shell
+openssl req -out client.example.com.csr -newkey rsa:2048 -nodes -keyout client.example.com.key -subj "/CN=client.example.com/O=example organization"
+openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in client.example.com.csr -out client.example.com.crt
+```
+
+Update the Gateway from the Quickstart to include an HTTPS listener that listens on port `443` and references the
+`example-cert` Secret:
+
+```shell
+kubectl patch gateway eg --type=json --patch '
+ - op: add
+ path: /spec/listeners/-
+ value:
+ name: https
+ protocol: HTTPS
+ port: 443
+ tls:
+ mode: Terminate
+ certificateRefs:
+ - kind: Secret
+ group: ""
+ name: example-cert
+ '
+```
+
+Verify the Gateway status:
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+Create a [ClientTrafficPolicy][] to enforce client validation using the CA Certificate as a trusted anchor.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+## Testing
+
+{{< tabpane text=true >}}
+{{% tab header="With External LoadBalancer Support" %}}
+
+Get the External IP of the Gateway:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+Query the example app through the Gateway:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \
+--cert client.example.com.crt --key client.example.com.key \
+--cacert example.com.crt https://www.example.com/get
+```
+
+Don't specify the client key and certificate in the above command, and ensure that the connection fails:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \
+--cacert example.com.crt https://www.example.com/get
+```
+
+{{% /tab %}}
+{{% tab header="Without LoadBalancer Support" %}}
+
+Get the name of the Envoy service created the by the example Gateway:
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+```
+
+Port forward to the Envoy service:
+
+```shell
+kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443 &
+```
+
+Query the example app through Envoy proxy:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \
+--cert client.example.com.crt --key client.example.com.key \
+--cacert example.com.crt https://www.example.com:8443/get
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+[ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy
diff --git a/site/content/en/v1.2/tasks/security/oidc.md b/site/content/en/v1.2/tasks/security/oidc.md
new file mode 100644
index 00000000000..d57e7d35ff3
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/oidc.md
@@ -0,0 +1,567 @@
+---
+title: "OIDC Authentication"
+---
+
+This task provides instructions for configuring [OpenID Connect (OIDC)][oidc] authentication.
+OpenID Connect (OIDC) is an authentication standard built on top of OAuth 2.0.
+It enables EG to rely on authentication that is performed by an OpenID Connect Provider (OP)
+to verify the identity of a user.
+
+Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure OIDC
+authentication.
+This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute][HTTPRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+EG OIDC authentication requires the redirect URL to be HTTPS. Follow the [Secure Gateways](../secure-gateways) guide
+to generate the TLS certificates and update the Gateway configuration to add an HTTPS listener.
+
+Verify the Gateway status:
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+Let's create an HTTPRoute that represents an application protected by OIDC.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the HTTPRoute status:
+
+```shell
+kubectl get httproute/myapp -o yaml
+```
+
+## OIDC Authentication for a HTTPRoute
+
+OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with
+the same OIDC configuration, or at the HTTPRoute level to authenticate each HTTPRoute with different OIDC configurations.
+
+This section demonstrates how to configure OIDC authentication for a specific HTTPRoute.
+
+### Register an OIDC application
+
+This task uses Google as the OIDC provider to demonstrate the configuration of OIDC. However, EG works with any OIDC
+providers, including Auth0, Azure AD, Keycloak, Okta, OneLogin, Salesforce, UAA, etc.
+
+Follow the steps in the [Google OIDC documentation][google-oidc] to register an OIDC application. Please make sure the
+redirect URL is set to the one you configured in the SecurityPolicy that you will create in the step below. In this example,
+the redirect URL is `https://www.example.com:8443/myapp/oauth2/callback`.
+
+After registering the application, you should have the following information:
+* Client ID: The client ID of the OIDC application.
+* Client Secret: The client secret of the OIDC application.
+
+### Create a kubernetes secret
+
+Next, create a kubernetes secret with the Client Secret created in the previous step. The secret is an Opaque secret,
+and the Client Secret must be stored in the key "client-secret".
+
+Note: please replace the ${CLIENT_SECRET} with the actual Client Secret that you got from the previous step.
+
+```shell
+kubectl create secret generic my-app-client-secret --from-literal=client-secret=${CLIENT_SECRET}
+```
+
+### Create a SecurityPolicy
+
+**Please notice that the `redirectURL` and `logoutPath` must match the target HTTPRoute.** In this example, the target
+HTTPRoute is configured to match the host `www.example.com` and the path `/myapp`, so the `redirectURL` must be prefixed
+with `https://www.example.com:8443/myapp`, and `logoutPath` must be prefixed with`/myapp`, otherwise the OIDC authentication
+will fail because the redirect and logout requests will not match the target HTTPRoute and therefore can't be processed
+by the OAuth2 filter on that HTTPRoute.
+
+Note: please replace the ${CLIENT_ID} in the below yaml snippet with the actual Client ID that you got from the OIDC provider.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/oidc-example -o yaml
+```
+
+### Testing
+
+Port forward gateway port to localhost:
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+
+kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443
+```
+
+Put www.example.com in the /etc/hosts file in your test machine, so we can use this host name to access the gateway from a browser:
+
+```shell
+...
+127.0.0.1 www.example.com
+```
+
+Open a browser and navigate to the `https://www.example.com:8443/myapp` address. You should be redirected to the Google
+login page. After you successfully login, you should see the response from the backend service.
+
+Clean the cookies in the browser and try to access `https://www.example.com:8443/foo` address. You should be able to see
+this page since the path `/foo` is not protected by the OIDC policy.
+
+## OIDC Authentication for a Gateway
+
+OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with
+the same OIDC configuration, or at the HTTPRoute level to authenticate each HTTPRoute with different OIDC configurations.
+
+This section demonstrates how to configure OIDC authentication for a Gateway.
+
+### Register an OIDC application
+
+If you haven't registered an OIDC application, follow the steps in the previous section to register an OIDC application.
+
+### Create a kubernetes secret
+
+If you haven't created a kubernetes secret, follow the steps in the previous section to create a kubernetes secret.
+
+### Create an HTTPRoute with a different subdomain
+
+Let's create another HTTPRoute in the same Gateway, but with a different subdomain.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the HTTPRoute status:
+
+```shell
+kubectl get httproute/foo -o yaml
+```
+
+### Create a SecurityPolicy
+
+Create or update the SecurityPolicy to target the Gateway instead of the HTTPRoute. **Please notice that the `redirectURL`
+and `logoutPath` must match one of the HTTPRoutes associated with the Gateway.** In this example, the target Gateway has
+three HTTPRoutes associated with it, one with the host `www.example.com` and the path `/myapp`, one with the host
+`www.example.com` and the path `/`, and one with the host `foo.example.com` and the path `/`. Any of these HTTPRoutes
+can be used to match the `redirectURL` and `logoutPath`.
+
+By default, the access token and ID token cookies are set to the host of the request, excluding subdomains. To allow the
+token cookies to be shared across subdomains and prevent users from having to log in again when switching between subdomains,
+the `cookieDomain` field needs to be set to the root domain. In this example, the root domain is `example.com`.
+
+Note: if a `cookieDomain` is added to an existing SecurityPolicy, the cookies in the browser must be cleared before sending a new request to the Gateway, otherwise the cookies with the old subdomain will take precedence and be sent to the Gateway, causing the OIDC authentication to fail.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/oidc-example -o yaml
+```
+
+### Update the Listener TLS certificate to support multiple subdomains
+
+Create a multi-domain wildcard certificate for `*.example.com`.
+
+```shell
+openssl req -out wildcard.csr -newkey rsa:2048 -nodes -keyout wildcard.key -subj "/CN=*.example.com/O=example organization"
+openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in wildcard.csr -out wildcard.crt
+```
+
+Replace the TLS certificate of the Gateway with the wildcard certificate.
+
+```shell
+kubectl delete secret example-cert
+kubectl create secret tls example-cert --key=wildcard.key --cert=wildcard.crt
+```
+
+### Testing
+
+If you haven't done so, follow the steps in the previous section to port forward gateway port to localhost and put
+www.example.com in the /etc/hosts file in your test machine.
+
+Also, put foo.example.com in the /etc/hosts file in your test machine.
+
+```shell
+...
+127.0.0.1 foo.example.com
+```
+
+Open a browser and navigate to the `https://www.example.com:8443/myapp` address. You should be redirected to the Google
+login page. After you successfully login, you should see the response from the backend service.
+
+You can also try to access `https://foo.example.com:8443` and `https://www.example.com:8443/bar` addresses. You should
+be able to see the response from the backend service since these HTTPRoutes are also protected by the same OIDC config,
+and the cookies are shared across subdomains.
+
+## Connect to an OIDC Provider with Self-Signed Certificate
+
+In some scenarios, the OIDC provider may use a self-signed certificate. To connect to an OIDC provider with a self-signed certificate, you need to configure it using the [Backend] resource within the [SecurityPolicy]. Additionally, use the [BackendTLSPolicy] to specify the CA certificate required to authenticate the OIDC provider.
+
+The following example demonstrates how to configure the OIDC provider with a self-signed certificate.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+For more information about [Backend] and [BackendTLSPolicy], refer to the [Backend Routing][backend-routing] and [Backend TLS: Gateway to Backend][backend-tls] tasks.
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the SecurityPolicy, the secret and the HTTPRoute:
+
+```shell
+kubectl delete securitypolicy/oidc-example
+kubectl delete secret/my-app-client-secret
+kubectl delete httproute/myapp
+kubectl delete httproute/foo
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../../contributions/develop) to get involved in the project.
+
+[oidc]: https://openid.net/connect/
+[google-oidc]: https://developers.google.com/identity/protocols/oauth2/openid-connect
+[SecurityPolicy]: ../../../api/extension_types#securitypolicy
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[Backend]: ../../../api/extension_types#backend
+[BackendTLSPolicy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
+[backend-routing]: ../traffic/backend
+[backend-tls]: ../backend-tls
diff --git a/site/content/en/v1.2/tasks/security/private-key-provider.md b/site/content/en/v1.2/tasks/security/private-key-provider.md
new file mode 100644
index 00000000000..24544f67973
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/private-key-provider.md
@@ -0,0 +1,653 @@
+---
+title: "Accelerating TLS Handshakes using Private Key Provider in Envoy"
+---
+
+TLS operations can be accelerated or the private key can be protected using specialized hardware. This can be leveraged in Envoy using [Envoy Private Key Provider](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#extensions-transport-sockets-tls-v3-privatekeyprovider) is added to Envoy.
+
+Today, there are two private key providers implemented in Envoy as contrib extensions:
+- [QAT in Envoy 1.24 release](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/private_key_providers/qat/v3alpha/qat.proto#extensions-private-key-providers-qat-v3alpha-qatprivatekeymethodconfig)
+- [CryptoMB in Envoy 1.20 release](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/private_key_providers/cryptomb/v3alpha/cryptomb.proto )
+
+Both of them are used to accelerate the TLS handshake through the hardware capabilities.
+
+This task will walk you through the steps required to configure TLS Termination mode for TCP traffic while also using the Envoy Private Key Provider to accelerate the TLS handshake by leveraging QAT and the HW accelerator available on Intel SPR/EMR Xeon server platforms.
+
+## Prerequisites
+
+{{< tabpane text=true >}}
+
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
+
+- Install Linux kernel 5.17 or similar
+- Ensure the node has QAT devices by checking the QAT physical function devices presented. [Supported Devices](https://intel.github.io/quickassist/qatlib/requirements.html#qat2-0-qatlib-supported-devices)
+
+ ```shell
+ echo `(lspci -d 8086:4940 && lspci -d 8086:4941 && lspci -d 8086:4942 && lspci -d 8086:4943 && lspci -d 8086:4946 && lspci -d 8086:4947) | wc -l` supported devices found.
+ ```
+
+- Enable IOMMU from BIOS
+- Enable IOMMU for Linux kernel
+
+ Figure out the QAT VF device id
+
+ ```shell
+ lspci -d 8086:4941 && lspci -d 8086:4943 && lspci -d 8086:4947
+ ```
+
+ Attach the QAT device to vfio-pci through kernel parameter by the device id gotten from previous command.
+
+ ```shell
+ cat /etc/default/grub:
+ GRUB_CMDLINE_LINUX="intel_iommu=on vfio-pci.ids=[QAT device id]"
+ update-grub
+ reboot
+ ````
+
+ Once the system is rebooted, check if the IOMMU has been enabled via the following command:
+
+ ```shell
+ dmesg| grep IOMMU
+ [ 1.528237] DMAR: IOMMU enabled
+ ```
+
+- Enable virtual function devices for QAT device
+
+ ```shell
+ modprobe vfio_pci
+ rmmod qat_4xxx
+ modprobe qat_4xxx
+ qat_device=$(lspci -D -d :[QAT device id] | awk '{print $1}')
+ for i in $qat_device; do echo 16|sudo tee /sys/bus/pci/devices/$i/sriov_numvfs; done
+ chmod a+rw /dev/vfio/*
+ ```
+
+- Increase the container runtime memory lock limit (using the containerd as example here)
+
+ ```shell
+ mkdir /etc/systemd/system/containerd.service.d
+ cat <>/etc/systemd/system/containerd.service.d/memlock.conf
+ [Service]
+ LimitMEMLOCK=134217728
+ EOF
+ ```
+
+ Restart the container runtime (for containerd, CRIO has similar concept)
+
+ ```shell
+ systemctl daemon-reload
+ systemctl restart containerd
+ ```
+
+- Install [Intel® QAT Device Plugin for Kubernetes](https://github.com/intel/intel-device-plugins-for-kubernetes)
+
+ ```shell
+ kubectl apply -k 'https://github.com/intel/intel-device-plugins-for-kubernetes/deployments/qat_plugin?ref=main'
+ ```
+
+ Verification of the plugin deployment and detection of QAT hardware can be confirmed by examining the resource allocations on the nodes:
+
+ ```shell
+ kubectl get node -o yaml| grep qat.intel.com
+ ```
+
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
+
+It required the node with 3rd generation Intel Xeon Scalable processor server processors, or later.
+- For kubernetes Cluster, if not all nodes that support Intel® AVX-512 in Kubernetes cluster, you need to add some labels to divide these two kinds of nodes manually or using [NFD](https://github.com/kubernetes-sigs/node-feature-discovery).
+
+ ```shell
+ kubectl apply -k https://github.com/kubernetes-sigs/node-feature-discovery/deployment/overlays/default?ref=v0.15.1
+ ```
+
+- Checking the available nodes with required cpu instructions:
+ - Check the node labels if using [NFD](https://github.com/kubernetes-sigs/node-feature-discovery):
+
+ ```shell
+ kubectl get nodes -l feature.node.kubernetes.io/cpu-cpuid.AVX512F,feature.node.kubernetes.io/cpu-cpuid.AVX512DQ,feature.node.kubernetes.io/cpu-cpuid.AVX512BW,feature.node.kubernetes.io/cpu-cpuid.AVX512VBMI2,feature.node.kubernetes.io/cpu-cpuid.AVX512IFMA
+ ```
+
+ - Check CPUIDS manually on the node if without using NFD:
+
+ ```shell
+ cat /proc/cpuinfo |grep avx512f|grep avx512dq|grep avx512bw|grep avx512_vbmi2|grep avx512ifma
+ ```
+
+{{% /tab %}}
+
+{{< /tabpane >}}
+
+## Installation
+
+* Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway.
+
+* Enable the EnvoyPatchPolicy feature, which will allow us to directly configure the Private Key Provider Envoy Filter, since Envoy Gateway does not directly expose this functionality.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{< boilerplate rollout-envoy-gateway >}}
+
+## Create gateway for TLS termination
+
+* Follow the instructions in [TLS Termination for TCP](./tls-termination) to setup a TCP gateway to terminate the TLS connection.
+
+* Update GatewayClass for using the envoyproxy image with contrib extensions and requests required resources.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+## Change EnvoyProxy configuration
+
+Using the envoyproxy image with contrib extensions and add qat resources requesting, ensure the k8s scheduler find out a machine with required resource.
+
+{{< tabpane text=true >}}
+
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
+
+Using the envoyproxy image with contrib extensions and add the node affinity to scheduling the Envoy Gateway pod on the machine with required CPU instructions.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Or using `preferredDuringSchedulingIgnoredDuringExecution` for best effort scheduling, or not doing any node affinity, just doing the random scheduling. The CryptoMB private key provider supports software fallback if the required CPU instructions aren't here.
+
+{{% /tab %}}
+
+{{< /tabpane >}}
+
+## Benchmark before enabling private key provider
+
+First follow the instructions in [TLS Termination for TCP](./tls-termination) to do the functionality test.
+
+Ensure the cpu frequency governor set as `performance`.
+
+```shell
+export NUM_CPUS=`lscpu | grep "^CPU(s):"|awk '{print $2}'`
+for i in `seq 0 1 $NUM_CPUS`; do sudo cpufreq-set -c $i -g performance; done
+```
+
+Using the nodeport as the example, fetch the node port from envoy gateway service.
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+export NODE_PORT=$(kubectl -n envoy-gateway-system get svc/$ENVOY_SERVICE -o jsonpath='{.spec.ports[0].nodePort}')
+```
+
+```shell
+echo "127.0.0.1 www.example.com" >> /etc/hosts
+```
+
+Benchmark the gateway with fortio.
+
+```shell
+fortio load -c 10 -k -qps 0 -t 30s -keepalive=false https://www.example.com:${NODE_PORT}
+```
+
+## Apply EnvoyPatchPolicy to enable private key provider
+
+{{< tabpane text=true >}}
+
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{% /tab %}}
+
+{{< /tabpane >}}
+
+## Benchmark after enabling private key provider
+
+First follow the instructions in [TLS Termination for TCP](./tls-termination) to do the functionality test again.
+
+Benchmark the gateway with fortio.
+
+```shell
+fortio load -c 64 -k -qps 0 -t 30s -keepalive=false https://www.example.com:${NODE_PORT}
+```
+
+## Benchmark Result
+
+You will see a performance boost after private key provider enabled. For example, you will get results as below.
+
+Without private key provider:
+
+```shell
+All done 43069 calls (plus 10 warmup) 6.966 ms avg, 1435.4 qps
+```
+
+{{< tabpane text=true >}}
+
+{{% tab header="QAT (Intel QuickAssist Technology)" %}}
+
+With QAT private key provider, the QPS is over 3 times than without private key provider
+
+```shell
+All done 134746 calls (plus 128 warmup) 28.505 ms avg, 4489.6 qps
+```
+
+{{% /tab %}}
+
+{{% tab header="CryptoMB" %}}
+
+With CryptoMB private key provider, the QPS is over 2 times than without private key provider.
+
+```shell
+All done 93983 calls (plus 128 warmup) 40.880 ms avg, 3130.5 qps
+```
+
+{{% /tab %}}
+
+{{< /tabpane >}}
diff --git a/site/content/en/v1.2/tasks/security/restrict-ip-access.md b/site/content/en/v1.2/tasks/security/restrict-ip-access.md
new file mode 100644
index 00000000000..ab8965d7966
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/restrict-ip-access.md
@@ -0,0 +1,196 @@
+---
+title: "IP Allowlist/Denylist"
+---
+
+This task provides instructions for configuring IP allowlist/denylist on Envoy Gateway. IP allowlist/denylist
+checks if an incoming request is from an allowed IP address before routing the request to a backend service.
+
+Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure IP allowlist/denylist.
+This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HTTPRoute] or [GRPCRoute][GRPCRoute] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## Configuration
+
+### Create a SecurityPolicy
+
+The below SecurityPolicy restricts access to the backend service by allowing requests only from the IP addresses `10.0.1.0/24`.
+
+In this example, the default action is set to `Deny`, which means that only requests from the specified IP addresses with `Allow`
+action are allowed, and all other requests are denied. You can also change the default action to `Allow` to allow all requests
+except those from the specified IP addresses with `Deny` action.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get securitypolicy/authorization-client-ip -o yaml
+```
+
+### Original Source IP
+
+It's important to note that the IP address used for allowlist/denylist is the original source IP address of the request.
+You can use a [ClientTrafficPolicy] to configure how Envoy Gateway should determine the original source IP address.
+
+For example, the below ClientTrafficPolicy configures Envoy Gateway to use the `X-Forwarded-For` header to determine the original source IP address.
+The `numTrustedHops` field specifies the number of trusted hops in the `X-Forwarded-For` header. In this example, the `numTrustedHops` is set to `1`,
+which means that the first rightmost IP address in the `X-Forwarded-For` header is used as the original source IP address.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+## Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+Send a request to the backend service without the `X-Forwarded-For` header:
+
+```shell
+curl -v -H "Host: www.example.com" "http://${GATEWAY_HOST}/"
+```
+
+You should see `403 Forbidden` in the response, indicating that the request is not allowed.
+
+```shell
+* Connected to 172.18.255.200 (172.18.255.200) port 80
+> GET /get HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.8.0-DEV
+> Accept: */*
+>
+* Request completely sent off
+< HTTP/1.1 403 Forbidden
+< content-length: 19
+< content-type: text/plain
+< date: Mon, 08 Jul 2024 04:23:31 GMT
+<
+* Connection #0 to host 172.18.255.200 left intact
+RBAC: access denied
+```
+
+Send a request to the backend service with the `X-Forwarded-For` header:
+
+```shell
+curl -v -H "Host: www.example.com" -H "X-Forwarded-For: 10.0.1.1" "http://${GATEWAY_HOST}/"
+```
+
+The request should be allowed and you should see the response from the backend service.
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the SecurityPolicy and the ClientTrafficPolicy
+
+```shell
+kubectl delete securitypolicy/authorization-client-ip
+kubectl delete clientTrafficPolicy/enable-client-ip-detection
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[SecurityPolicy]: ../../../contributions/design/security-policy
+[ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[GRPCRoute]: https://gateway-api.sigs.k8s.io/api-types/grpcroute
diff --git a/site/content/en/v1.2/tasks/security/secure-gateways.md b/site/content/en/v1.2/tasks/security/secure-gateways.md
new file mode 100644
index 00000000000..2c8d5043812
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/secure-gateways.md
@@ -0,0 +1,599 @@
+---
+title: "Secure Gateways"
+---
+
+This task will help you get started using secure Gateways.
+This task uses a self-signed CA, so it should be used for testing and demonstration purposes only.
+
+## Prerequisites
+
+- OpenSSL to generate TLS assets.
+
+## Installation
+
+{{< boilerplate prerequisites >}}
+
+## TLS Certificates
+
+Generate the certificates and keys used by the Gateway to terminate client TLS connections.
+
+Create a root certificate and private key to sign certificates:
+
+```shell
+openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
+```
+
+Create a certificate and a private key for `www.example.com`:
+
+```shell
+openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization"
+openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt
+```
+
+Store the cert/key in a Secret:
+
+```shell
+kubectl create secret tls example-cert --key=www.example.com.key --cert=www.example.com.crt
+```
+
+Update the Gateway from the Quickstart to include an HTTPS listener that listens on port `443` and references the
+`example-cert` Secret:
+
+```shell
+kubectl patch gateway eg --type=json --patch '
+ - op: add
+ path: /spec/listeners/-
+ value:
+ name: https
+ protocol: HTTPS
+ port: 443
+ tls:
+ mode: Terminate
+ certificateRefs:
+ - kind: Secret
+ group: ""
+ name: example-cert
+ '
+```
+
+Verify the Gateway status:
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+## Testing
+
+{{< tabpane text=true >}}
+{{% tab header="With External LoadBalancer Support" %}}
+
+Get the External IP of the Gateway:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+Query the example app through the Gateway:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \
+--cacert example.com.crt https://www.example.com/get
+```
+
+{{% /tab %}}
+{{% tab header="Without LoadBalancer Support" %}}
+
+Get the name of the Envoy service created the by the example Gateway:
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+```
+
+Port forward to the Envoy service:
+
+```shell
+kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443 &
+```
+
+Query the example app through Envoy proxy:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \
+--cacert example.com.crt https://www.example.com:8443/get
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+
+## Multiple HTTPS Listeners
+
+Create a TLS cert/key for the additional HTTPS listener:
+
+```shell
+openssl req -out foo.example.com.csr -newkey rsa:2048 -nodes -keyout foo.example.com.key -subj "/CN=foo.example.com/O=example organization"
+openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in foo.example.com.csr -out foo.example.com.crt
+```
+
+Store the cert/key in a Secret:
+
+```shell
+kubectl create secret tls foo-cert --key=foo.example.com.key --cert=foo.example.com.crt
+```
+
+Create another HTTPS listener on the example Gateway:
+
+```shell
+kubectl patch gateway eg --type=json --patch '
+ - op: add
+ path: /spec/listeners/-
+ value:
+ name: https-foo
+ protocol: HTTPS
+ port: 443
+ hostname: foo.example.com
+ tls:
+ mode: Terminate
+ certificateRefs:
+ - kind: Secret
+ group: ""
+ name: foo-cert
+ '
+```
+
+Update the HTTPRoute to route traffic for hostname `foo.example.com` to the example backend service:
+
+```shell
+kubectl patch httproute backend --type=json --patch '
+ - op: add
+ path: /spec/hostnames/-
+ value: foo.example.com
+ '
+```
+
+Verify the Gateway status:
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+Follow the steps in the [Testing section](#testing) to test connectivity to the backend app through both Gateway
+listeners. Replace `www.example.com` with `foo.example.com` to test the new HTTPS listener.
+
+## Cross Namespace Certificate References
+
+A Gateway can be configured to reference a certificate in a different namespace. This is allowed by a [ReferenceGrant][]
+created in the target namespace. Without the ReferenceGrant, a cross-namespace reference is invalid.
+
+Before proceeding, ensure you can query the HTTPS backend service from the [Testing section](#testing).
+
+To demonstrate cross namespace certificate references, create a ReferenceGrant that allows Gateways from the "default"
+namespace to reference Secrets in the "envoy-gateway-system" namespace:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Delete the previously created Secret:
+
+```shell
+kubectl delete secret/example-cert
+```
+
+The Gateway HTTPS listener should now surface the `Ready: False` status condition and the example HTTPS backend should
+no longer be reachable through the Gateway.
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+Recreate the example Secret in the `envoy-gateway-system` namespace:
+
+```shell
+kubectl create secret tls example-cert -n envoy-gateway-system --key=www.example.com.key --cert=www.example.com.crt
+```
+
+Update the Gateway HTTPS listener with `namespace: envoy-gateway-system`, for example:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+The Gateway HTTPS listener status should now surface the `Ready: True` condition and you should once again be able to
+query the HTTPS backend through the Gateway.
+
+Lastly, test connectivity using the above [Testing section](#testing).
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the Secrets:
+
+```shell
+kubectl delete secret/example-cert
+kubectl delete secret/foo-cert
+```
+
+# RSA + ECDSA Dual stack certificates
+
+This section gives a walkthrough to generate RSA and ECDSA derived certificates and keys for the Server, which can then be configured in the Gateway listener, to terminate TLS traffic.
+
+## Prerequisites
+
+Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+Follow the steps in the [TLS Certificates](#tls-certificates) section to generate self-signed RSA derived Server certificate and private key, and configure those in the Gateway listener configuration to terminate HTTPS traffic.
+
+## Pre-checks
+
+While testing in [Cluster without External LoadBalancer Support](#clusters-without-external-loadbalancer-support), we can query the example app through Envoy proxy while enforcing an RSA cipher, as shown below:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \
+--cacert example.com.crt https://www.example.com:8443/get -Isv --ciphers ECDHE-RSA-CHACHA20-POLY1305 --tlsv1.2 --tls-max 1.2
+```
+
+Since the Secret configured at this point is an RSA based Secret, if we enforce the usage of an ECDSA cipher, the call should fail as follows
+
+```shell
+$ curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \
+--cacert example.com.crt https://www.example.com:8443/get -Isv --ciphers ECDHE-ECDSA-CHACHA20-POLY1305 --tlsv1.2 --tls-max 1.2
+
+* Added www.example.com:8443:127.0.0.1 to DNS cache
+* Hostname www.example.com was found in DNS cache
+* Trying 127.0.0.1:8443...
+* Connected to www.example.com (127.0.0.1) port 8443 (#0)
+* ALPN: offers h2
+* ALPN: offers http/1.1
+* Cipher selection: ECDHE-ECDSA-CHACHA20-POLY1305
+* CAfile: example.com.crt
+* CApath: none
+* (304) (OUT), TLS handshake, Client hello (1):
+* error:1404B410:SSL routines:ST_CONNECT:sslv3 alert handshake failure
+* Closing connection 0
+```
+
+Moving forward in the doc, we will be configuring the existing Gateway listener to accept both kinds of ciphers.
+
+## TLS Certificates
+
+Reuse the CA certificate and key pair generated in the [Secure Gateways](#tls-certificates) task and use this CA to sign both RSA and ECDSA Server certificates.
+Note the CA certificate and key names are `example.com.crt` and `example.com.key` respectively.
+
+
+Create an ECDSA certificate and a private key for `www.example.com`:
+
+```shell
+openssl ecparam -noout -genkey -name prime256v1 -out www.example.com.ecdsa.key
+openssl req -new -SHA384 -key www.example.com.ecdsa.key -nodes -out www.example.com.ecdsa.csr -subj "/CN=www.example.com/O=example organization"
+openssl x509 -req -SHA384 -days 365 -in www.example.com.ecdsa.csr -CA example.com.crt -CAkey example.com.key -CAcreateserial -out www.example.com.ecdsa.crt
+```
+
+Store the cert/key in a Secret:
+
+```shell
+kubectl create secret tls example-cert-ecdsa --key=www.example.com.ecdsa.key --cert=www.example.com.ecdsa.crt
+```
+
+Patch the Gateway with this additional ECDSA Secret:
+
+```shell
+kubectl patch gateway eg --type=json --patch '
+ - op: add
+ path: /spec/listeners/1/tls/certificateRefs/-
+ value:
+ name: example-cert-ecdsa
+ '
+```
+
+Verify the Gateway status:
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+## Testing
+
+Again, while testing in Cluster without External LoadBalancer Support, we can query the example app through Envoy proxy while enforcing an RSA cipher, which should work as it did before:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \
+--cacert example.com.crt https://www.example.com:8443/get -Isv --ciphers ECDHE-RSA-CHACHA20-POLY1305 --tlsv1.2 --tls-max 1.2
+```
+
+```shell
+...
+* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
+* TLSv1.2 (IN), TLS handshake, Finished (20):
+* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
+...
+```
+
+Additionally, querying the example app while enforcing an ECDSA cipher should also work now:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \
+--cacert example.com.crt https://www.example.com:8443/get -Isv --ciphers ECDHE-ECDSA-CHACHA20-POLY1305 --tlsv1.2 --tls-max 1.2
+```
+
+```shell
+...
+* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
+* TLSv1.2 (IN), TLS handshake, Finished (20):
+* SSL connection using TLSv1.2 / ECDHE-ECDSA-CHACHA20-POLY1305
+...
+```
+
+# SNI based Certificate selection
+
+This sections gives a walkthrough to generate multiple certificates corresponding to different FQDNs. The same Gateway listener can then be configured to terminate TLS traffic for multiple FQDNs based on the SNI matching.
+
+## Prerequisites
+
+Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+Follow the steps in the [TLS Certificates](#tls-certificates) section to generate self-signed RSA derived Server certificate and private key, and configure those in the Gateway listener configuration to terminate HTTPS traffic.
+
+## Additional Configurations
+
+Using the [TLS Certificates](#tls-certificates) section, we first generate additional Secret for another Host `www.sample.com`.
+
+```shell
+openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=sample Inc./CN=sample.com' -keyout sample.com.key -out sample.com.crt
+
+openssl req -out www.sample.com.csr -newkey rsa:2048 -nodes -keyout www.sample.com.key -subj "/CN=www.sample.com/O=sample organization"
+openssl x509 -req -days 365 -CA sample.com.crt -CAkey sample.com.key -set_serial 0 -in www.sample.com.csr -out www.sample.com.crt
+
+kubectl create secret tls sample-cert --key=www.sample.com.key --cert=www.sample.com.crt
+```
+
+Note that all occurrences of `example.com` were just replaced with `sample.com`
+
+
+Next we update the `Gateway` configuration to accommodate the new Certificate which will be used to Terminate TLS traffic:
+
+```shell
+kubectl patch gateway eg --type=json --patch '
+ - op: add
+ path: /spec/listeners/1/tls/certificateRefs/-
+ value:
+ name: sample-cert
+ '
+```
+
+Finally, we update the HTTPRoute to route traffic for hostname `www.sample.com` to the example backend service:
+
+```shell
+kubectl patch httproute backend --type=json --patch '
+ - op: add
+ path: /spec/hostnames/-
+ value: www.sample.com
+ '
+```
+
+## Testing
+
+{{< tabpane text=true >}}
+{{% tab header="With External LoadBalancer Support" %}}
+
+Refer to the steps mentioned earlier under [Testing in clusters with External LoadBalancer Support](#testing)
+
+
+{{% /tab %}}
+{{% tab header="Without LoadBalancer Support" %}}
+
+Get the name of the Envoy service created the by the example Gateway:
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+```
+
+Port forward to the Envoy service:
+
+```shell
+kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443 &
+```
+
+Query the example app through Envoy proxy:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \
+--cacert example.com.crt https://www.example.com:8443/get -I
+```
+
+Similarly, query the sample app through the same Envoy proxy:
+
+```shell
+curl -v -HHost:www.sample.com --resolve "www.sample.com:8443:127.0.0.1" \
+--cacert sample.com.crt https://www.sample.com:8443/get -I
+```
+
+Since the multiple certificates are configured on the same Gateway listener, Envoy was able to provide the client with appropriate certificate based on the SNI in the client request.
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+## Customize Gateway TLS Parameters
+
+In addition to enablement of TLS with Gateway-API, Envoy Gateway supports customizing TLS parameters.
+To achieve this, the [ClientTrafficPolicy][] resource can be used to specify TLS parameters.
+We will customize the minimum supported TLS version in this example to TLSv1.3.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+## Testing TLS Parameters
+
+Attempt to connecting using an unsupported TLS version:
+
+```shell
+curl -v -HHost:www.sample.com --resolve "www.sample.com:8443:127.0.0.1" \
+--cacert sample.com.crt --tlsv1.2 --tls-max 1.2 https://www.sample.com:8443/get -I
+
+[...]
+
+* ALPN: curl offers h2,http/1.1
+* (304) (OUT), TLS handshake, Client hello (1):
+* LibreSSL/3.3.6: error:1404B42E:SSL routines:ST_CONNECT:tlsv1 alert protocol version
+* Closing connection
+curl: (35) LibreSSL/3.3.6: error:1404B42E:SSL routines:ST_CONNECT:tlsv1 alert protocol version
+```
+
+The output shows that the connection fails due to an unsupported TLS protocol version used by the client. Now, connect
+to the Gateway without specifying a client version, and note that the connection is established with TLSv1.3.
+
+```shell
+curl -v -HHost:www.sample.com --resolve "www.sample.com:8443:127.0.0.1" \
+--cacert sample.com.crt https://www.sample.com:8443/get -I
+
+[...]
+
+* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
+
+[ReferenceGrant]: https://gateway-api.sigs.k8s.io/api-types/referencegrant/
+[ClientTrafficPolicy]: ../../api/extension_types#clienttrafficpolicy
\ No newline at end of file
diff --git a/site/content/en/v1.2/tasks/security/threat-model.md b/site/content/en/v1.2/tasks/security/threat-model.md
new file mode 100644
index 00000000000..a16319f9d72
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/threat-model.md
@@ -0,0 +1,665 @@
+---
+title: "Threat Model"
+---
+
+# Envoy Gateway Threat Model and End User Recommendations
+
+## About
+
+This work was performed by [ControlPlane](https://control-plane.io/) and commissioned by the [Linux Foundation](https://www.linuxfoundation.org/). ControlPlane is a global cloud native and open source cybersecurity consultancy, trusted as the partner of choice in securing: multinational banks; major public clouds; international financial institutions; critical national infrastructure programs; multinational oil and gas companies, healthcare and insurance providers; and global media firms.
+
+## Threat Modelling Team
+
+James Callaghan, Torin van den Bulk, Eduardo Olarte
+
+## Reviewers
+
+Arko Dasgupta, Matt Turner, Zack Butcher, Marco De Benedictis
+
+## Introduction
+
+As we embrace the proliferation of microservice-based architectures in the cloud-native landscape, simplicity in setup and configuration becomes paramount as DevOps teams face the challenge of choosing between numerous similar technologies. One such choice which every team deploying to Kubernetes faces is what to use as an ingress controller. With a plethora of options available, and the existence of vendor-specific annotations leading to small inconsistencies between implementations, the [Gateway API](https://gateway-api.sigs.k8s.io/) project was introduced by the SIG-NETWORK community, with the goal of eventually replacing the Ingress resource.
+
+Envoy Gateway is configured by Gateway API resources, and serves as an intuitive and feature-rich wrapper over the widely acclaimed Envoy Proxy. With a convenient setup based on Kubernetes (K8s) manifests, Envoy Gateway streamlines the management of Envoy Proxy instances in an edge-proxy setting, reducing the operational overhead of managing low-level Envoy configurations. Envoy Gateway benefits cloud-native DevOps teams through its role-oriented configuration, providing granular control based on Role-Based Access Control (RBAC) principles. These features form the basis of our exploration into Envoy Gateway and the rich feature set it brings to the table.
+
+In this threat model, we aim to provide an analysis of Envoy Gateway's design components and their capabilities (at version 1.0) through a threat-driven approach. It should be noted that this does not constitute a security audit of the Envoy Gateway project, but instead focuses on different possible deployment topologies for Envoy Gateway with the goal of deriving recommendations and best practice guidance for end users.
+
+The Envoy Gateway project recommends a [multi-tenancy model](../operations/deployment-mode#multi-tenancy) whereby each tenant deploys their own Envoy Gateway controller in a namespace which they own. We will also explore the implications and risks associated with multiple tenants using a shared controller.
+
+### Scope
+
+The primary focus of this threat model is to identify and assess security risks associated with deploying and operating Envoy Gateway within a multi-tenant Kubernetes (K8s) cluster. This model aims to provide a comprehensive understanding of the system, its transmission points, and potential vulnerabilities to enumerated threats.
+
+### In Scope
+
+**Envoy Gateway**: As the primary focus of this threat model, all aspects of Envoy Gateway, including its configuration, deployment, and operation will be analysed. This includes how the gateway manages TLS certificates, authentication, service-to-service traffic routing, and more.
+
+**Kubernetes Cluster**: Configuration and operation of the underlying Kubernetes cluster, including how it manages network policies, access control, and resource isolation for different namespaces/tenants in relation to Envoy will be considered.
+
+**Tenant Workloads**: Tenant workloads (and the pods they run on) will be considered, focusing on how they interact with the Envoy Gateway and potential vulnerabilities that could be exploited.
+
+#### Out of Scope
+
+This threat model will not consider security risks associated with the underlying infrastructure (e.g., EC2 compute instances and S3 buckets) or non-Envoy related components within the Kubernetes Cluster. It will focus solely on the Envoy Gateway and its interaction with the Kubernetes cluster and tenant workloads.
+
+Implementation of Envoy Gateway as an egress traffic controller is out of scope for this threat model and will not be considered in the report's findings.
+
+### Related Resources
+
+[Introducing Envoy Gateway](https://blog.envoyproxy.io/introducing-envoy-gateway-ad385cc59532)
+
+[Envoy Proxy Threat Model](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/security/threat_model#threat-model)
+
+[Configuring Envoy as an Edge Proxy](https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge#best-practices-edge)
+
+[Envoy Gateway Deployment Mode](../operations/deployment-mode)
+
+[Kubernetes Gateway API Security Model](https://gateway-api.sigs.k8s.io/concepts/security-model/)
+
+## Architecture Overview
+
+### Summary
+
+To provide an in-depth look into both the system design and end-user deployment of Envoy Gateway, we will be focusing on the [Deployment Architecture Diagram](#deployment-architecture-diagram) below.
+
+The Deployment Architecture Diagram provides a high-level model of an end-user deployment of Envoy Gateway. For simplicity, we will look at different deployment topologies on a single multi-tenant Kubernetes cluster. Envoy Gateway operates as an edge proxy within this environment, handling the traffic flow between external interfaces and services within the cluster. The example will use two Envoy Gateway controllers - one dedicated controller for a single tenant, and one shared controller for two other tenants. Each Envoy Gateway controller will accept a single GatewayClass resource.
+
+### Deployment Architecture Diagram
+
+As Envoy Gateway implements the [Kubernetes GatewayAPI](https://gateway-api.sigs.k8s.io/concepts/api-overview/), this threat model will focus on the key objects in the Gateway API resource model:
+
+1. **GatewayClass:** defines a set of gateways with a commonconfiguration and behaviour. It is a cluster scoped resource.
+
+2. **Gateway:** requests a point where traffic can be translated to Services within the cluster.
+
+3. **Routes:** describe how traffic coming via the Gateway maps to theServices.
+
+At the time of writing, Envoy Gateway only supports a Kubernetes provider. As such, we will consider a reference architecture where multiple teams are working on the same Kubernetes cluster within different namespaces (Tenant A, B, & C). We will assume that some teams have similar security and performance needs, and a decision has been made to use a shared Gateway. However, we will also consider the case that some teams require dedicated Gateways, perhaps for compliance reasons or requirements driven by an internal threat model.
+
+We will consider the following organisational roles, as per the [Gateway API security model](https://gateway-api.sigs.k8s.io/concepts/security-model/):
+
+1. **Infrastructure provider**: The infrastructure provider (infra) is responsible for the overall environment that the cluster(s) are operating in. Examples include: the cloud provider (AWS, Azure, GCP, ...) or the PaaS provider in a company.
+
+2. **Cluster operator**: The cluster operator (ops) is responsible for administration of entire clusters. They manage policies, network access, application permissions.
+
+3. **Application developer**: The application developer (dev) is responsible for defining their application configuration (e.g. timeouts, request matching/filter) and Service composition (e.g. path routing to backends).
+
+4. **Application admin**: The application admin has administrative access to some namespaces within a cluster, but not the cluster as a whole.
+
+Our threat model will be based on the high-level setup shown below, where Envoy is used in an edge-proxy scenario:
+
+![Architecture](/img/architecture_threat_model.png)
+
+The following use cases will be considered, in line with the [Envoy Gateway tasks](../quickstart):
+
+1. Routing and controlling traffic, including:
+ a. HTTP \
+ b. TCP \
+ c. UDP \
+ d. gRPC \
+ e.TLS passthrough
+2. TLS termination
+3. Request Authentication
+4. Rate Limiting
+
+## Key Assumptions
+
+This section outlines the foundational premises that shape our analysis and recommendations for the deployment and management of Envoy Gateway within an organisation. The key assumptions are as follows:
+
+**1. Kubernetes Provider**: For the purposes of this analysis, we assume that a K8s provider will be used to host the cluster.
+
+**2. Multi-tenant cluster**: In order to produce a broad set of recommendations, it is assumed that within the single cluster, there is:
+
+- A dedicated cluster operation (ops) team responsible for maintaining the core cluster infrastructure.
+
+- Multiple application teams who wish to define their own Gateway resources, which will route traffic to their respective applications.
+
+**3. Soft multi-tenancy model**: It is assumed that co-tenants will have some level of trust between themselves, and will not act in an overtly hostile manner to each other.
+
+**4. Ingress Control**: It's assumed that Envoy Gateway is the only ingress controller in the K8s cluster as multiple controllers can lead to complex routing challenges and introduce out-of-scope security vulnerabilities.
+
+**5. Container Security**: This threat model focuses on evaluating the security of the Envoy Gateway and Envoy Proxy images. All other container images running in tenant clusters, not associated with the edge proxy deployment, are assumed to be secure and obtained from trusted registries such as Docker Hub or Google Container Registry (GCR).
+
+**6. Cloud Provider Security**: It is assumed that the K8s cluster is running on secure cloud infrastructure provided by a trusted Cloud Service Provider (CSP) such as AWS, GCP, or Azure Cloud.
+
+## Data
+
+### Data Dictionary
+
+Ultimately, the data of interest in a threat model is the business data processed by the system in question. However, in the case of this threat model, we are looking at a generic deployment architecture involving Envoy Gateway in order to draw out a set of generalised threats which can be considered by teams looking to adopt an implementation of Gateway API. As such, we do not know the business impacts of a compromise of confidentiality, integrity or availability that would typically be captured in a data impact assessment. Instead, will we base our threat assessment on high-level groupings of data structures used in the configuration and operation of the general use cases considered (e.g. HTTP routing, TLS termination, request authentication etc.). We will then assign a confidentiality, integrity and availability impact based on a worst-case scenario of how each compromise could potentially affect business data processed by the generic deployment.
+
+| Data Name / Type | Notes | Confidentiality | Integrity | Availability |
+| ------------ | ------------ | ------------ |--------------- | ------------ |
+| Static Configuration Data | Static configuration data is used to configure Envoy Gateway at startup. This data structure allows for a Provider to be set, which Envoy Gateway calls to establish its runtime configuration, resolve services and persist data. Unauthorised modification of static configuration data could enable the Envoy Gateway admin interface to be configured, logging parameters to be modified, global rate limiting configuration to be misconfigured, or malicious extensions registered for the Envoy Gateway Control Plane. A compromise of confidentiality could potentially give an attacker some useful reconnaissance information. A compromise of the availability of this information at startup time would result in Envoy Gateway starting with default parameters. | Medium | High | Low |
+| Dynamic Configuration Data | Dynamic configuration data represents the desired state of the Data Plane, and is defined through Envoy Gateway and Gateway API Kubernetes resources. Unauthorised modification of this data could lead to vulnerabilities in an organisation’s Data Plane infrastructure via misconfiguration of an EnvoyProxy custom resource. Misconfiguration of Gateway API objects such as HTTPRoutes or TLSRoutes could result in traffic being directed to incorrect backends. A compromise of confidentiality could potentially give an attacker some useful reconnaissance information. A compromise of the availability of this information could result in tenant application traffic not being routable until the configuration is recovered and reapplied. | Medium | High | Medium |
+| TLS Private Keys | TLS Private Keys, typically in PEM format, are used to initiate secure connections and encrypt communications. In the context of this threat model, private keys will be associated with the server side of an inbound TLS connection being terminated at a secure gateway configured through Envoy Gateway. Unauthorised exposure could lead to security threats such as person-in-the-middle attacks, whereby the confidentiality or integrity of business data could be compromised. A compromise of integrity may lead to similar consequences if an attacker could insert their own key material. An availability compromise could lead to tenant services being unavailable until new key material is generated and an appropriate CSR submitted. | High | High | Medium |
+| TLS Certificates | X.509 certificates represent the binding of a public key (associated with the private key described above) to an identity in a TLS handshake. If an attacker could compromise the integrity of a certificate, they may be able to bind the identity of a TLS termination point to a key pair under their control, enabling person-in-the middle attacks. An availability compromise could lead to tenant services being unavailable until new key material is generated and an appropriate CSR submitted. | Low | High | Medium |
+| JWKs | JWK (JSON Web Key) containing a public key used to validate JWTs for the client authentication use case considered in this threat model. If an attacker could compromise the integrity of a JWK or JSON web key set (JWKS), they could potentially authenticate to a service maliciously. Unavailability of an endpoint exposing JWKs could lead to client requests which require authentication being denied. | Low | High | Medium |
+| JWTs | JWTs, formatted as compact, URL-safe JSON data structures, are utilised for the client authentication use case considered in this threat model. Maintaining their confidentiality and integrity is vital to prevent unauthorised access and ensure correct user identification. | High | High | Low |
+| OIDC credentials | In OIDC authentication scenarios, the application credentials are represented by a client ID and a client secret. A compromise of its confidentiality or integrity could allow malicious actors to impersonate the application, potentially being able to access resources on behalf of the application and request ID tokens on behalf of users. Unavailability of this data would produce a rejection of the requests coming from legitimate users. | High | High | Medium |
+| Basic authentiation password hashes | In basic authentication scenarios, passwords are stored as Kubernetes secrets in [htpasswd](https://httpd.apache.org/docs/current/programs/htpasswd.html) format, where each entry is formed by the username and the hashed password. A compromise of these credentials' confidentiality and integrity could lead to unauthorised access to the application. Unavailability of these credentials will cause login failures from the application users. | High | High | Medium |
+
+### CIA Impact Assessment
+
+| Priority | Description |
+| --- | --- |
+| **Confidentiality** | |
+| High | Compromise of sensitive client data |
+| Medium | Information leaked which could be useful for attacker reconnaissance |
+| Low | Non-sensitive information leakage |
+| **Integrity** | |
+| High | Compromise of source code repositories and gateway deployments |
+| Medium | Traffic routing fails due to misconfiguration / invalid configuration |
+| Low | Non-critical operation is blocked due to misconfiguration / invalid configuration |
+| **Availability** | |
+| High | Large scale DoS |
+| Medium | Tenant application is blocked for a significant period |
+| Low | Tenant application is blocked for a short period |
+
+### Data Flow Diagrams
+
+The Data Flow Diagrams (DFDs) below describe the flow of data between the various processes, entities and data stores in a system, as well as the trust boundaries between different user roles and network interfaces. The DFDs are drawn at two different levels, starting at L0 (high-level system view) and increasing in granularity (to L1).
+
+### DFD L0
+
+![DFD L0](/img/DFDL0.png)
+
+### DFD L1
+
+![DFD L1](/img/DFDL1.png)
+
+## Key Threats and Recommendations
+
+The scope of this threat model led to us categorising threats into priorities of High, Medium or Low; notably in a production implementation some of the threats' prioritisation may be upgraded or downgraded depending on the business context and data classification.
+
+### Risk vs. Threat
+
+For every finding, the risk and threat are stated. Risk defines the potential for negative outcome while threat defines the event that causes the negative outcome.
+
+### Threat Categorization
+
+Throughout this threat model, we categorised threats into different areas based on their origin and the segment of the system that they impact. Here's an overview of each category:
+
+**Container Security (CS)**: These threats are general to containerised applications. Therefore, they are not associated with Envoy Gateway or the Gateway API and could occur in most containerised workloads. They can originate from misconfigurations or vulnerabilities in the orchestrator or the container.
+
+**Gateway API (GW)**: These are threats related to the Gateway API that could affect any of its implementations. Malicious actors could benefit from misconfigurations or excessive permissions on the Gateway API resources (e.g. xRoutes or Gateways) to compromise the confidentiality, integrity, or availability of the application.
+
+**Envoy Gateway (EG)**: These threats are associated with specific configurations or features from Envoy Gateway or Envoy Proxy. If not set properly, these features could be leveraged to gain unauthorised access to protected resources.
+
+### Threat Actors
+
+In order to provide a realistic set of threats that is applicable to most organisations, we de-scoped the most advanced and hard to mitigate threat actors as described below:
+
+#### In Scope Threat Actors
+
+When considering internal threat actors, we chose to follow the [security model](https://gateway-api.sigs.k8s.io/concepts/security-model/) of the Kubernetes Gateway API.
+
+##### Internal Attacker
+
+- Cluster Operator: The cluster operator (ops) is responsible for administration of entire clusters. They manage policies, network access, application permissions.
+
+- Application Developer: The application developer (dev) is responsible for defining their application configuration (e.g. timeouts, request matching/filter) and Service composition (e.g. path routing to backends).
+
+- Application Administrator: The application admin has administrative access to some namespaces within a cluster, but not the cluster as a whole.
+
+##### External Attacker
+
+- Vandal: Script kiddie, trespasser
+
+- Motivated Individual: Political activist, thief, terrorist
+
+- Organised Crime: Syndicates, state-affiliated groups
+
+#### Out of Scope Threat Actors
+
+##### External Actors
+
+- Infrastructure Provider: The infrastructure provider (infra) is responsible for the overall environment that the cluster(s) are operating in. Examples include: the cloud provider, or the PaaS provider in a company.
+
+- Cloud Service Insider: Employee, external contractor, temporary worker
+
+- Foreign Intelligence Services (FIS): Nation states
+
+## High Priority Findings
+
+### EGTM-001 Usage of self-signed certificates
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-001|EGTM-GW-001|Gateway API|High|
+
+ **Risk**: Self-signed certificates (which do not comply with PKI best practices) could lead to unauthorised access to the private key associated with the certificate used for inbound TLS termination at Envoy Proxy, compromising the confidentiality and integrity of proxied traffic.
+
+ **Threat**: Compromise of the private key associated with the certificate used for inbound TLS terminating at Envoy Proxy.
+
+ **Recommendation**: The Envoy Gateway quickstart demonstrates how to set up a Secure Gateway using an example where a self-signed root certificate is created using openssl. As stated in the Envoy Gateway documentation, this is not a suitable configuration for Production usage. It is recommended that PKI best practices are followed, whereby certificates are signed by an Intermediary CA which sits underneath an organisational \'offline\' Root CA.
+
+ PKI best practices should also apply to the management of client certificates when using mTLS. The Envoy Gateway [mTLS](../security/mutual-tls) task shows how to set up client certificates using self-signed certificates. In the same way as gateway certificates and, as mentioned in the documentation, this configuration should not be used in production environments.
+
+### EGTM-002 Private keys are stored as Kubernetes secrets
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|--------------|------------------------|-----------------|
+|EGTM-002|EGTM-CS-001|Container Security|High|
+
+ **Risk**: There is a risk that a threat actor could compromise the Kubernetes secret containing the Envoy private key, allowing the attacker to decrypt Envoy Proxy traffic, compromising the confidentiality of proxied traffic.
+
+ **Threat**: Kubernetes secret containing the Envoy private key is compromised and used to decrypt proxied traffic.
+
+ **Recommendation**: Certificate management best practices mandate short-lived key material where practical, meaning that a mechanism for rotation of private keys and certificates is required, along with a way for certificates to be mounted into Envoy containers. If Kubernetes secrets are used, when a certificate expires, the associated secret must be updated, and Envoy containers must be redeployed. Instead of a manual configuration, it is recommended that [cert-manager](https://github.com/cert-manager/cert-manager) is used.
+
+### EGTM-004 Usage of ClusterRoles with wide permissions
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|--------------|------------------------|-----------------|
+|EGTM-004|EGTM-K8-002|Container Security|High|
+
+ **Risk**: There is a risk that a threat actor could abuse misconfigured RBAC to access the Envoy Gateway ClusterRole (envoy-gateway-role) and use it to expose all secrets across the cluster, thus compromising the confidentiality and integrity of tenant data.
+
+ **Threat**: Compromised Envoy Gateway or misconfigured ClusterRoleBinding (envoy-gateway-rolebinding) to Envoy Gateway ClusterRole (envoy-gateway-role), provides access to resources and secrets in different namespaces.
+
+ **Recommendation**: Users should be aware that Envoy Gateway uses a ClusterRole (envoy-gateway-role) when deployed via the Helm chart, to allow management of Envoy Proxies across different namespaces. This ClusterRole is powerful and includes the ability to read secrets in namespaces which may not be within the purview of Envoy Gateway.
+
+ Kubernetes best-practices involve restriction of ClusterRoleBindings, with the use of RoleBindings where possible to limit access per namespace by specifying the namespace in metadata. Namespace isolation reduces the impact of compromise from cluster-scoped roles. Ideally, fine-grained K8s roles should be created per the principle of least privilege to ensure they have the minimum access necessary for role functions.
+
+ The pull request \#[1656](https://github.com/envoyproxy/gateway/pull/1656) introduced the use of Roles and RoleBindings in [namespaced mode](https://gateway.envoyproxy.io/latest/api/extension_types/#kuberneteswatchmode). This feature can be leveraged to reduce the amount of permissions required by the Envoy Gateway.
+
+### EGTM-007 Misconfiguration of Envoy Gateway dynamic config
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-007|EGTM-EG-002|Envoy Gateway|High|
+
+ **Risk**: There is a risk that a threat actor could exploit misconfigured Kubernetes RBAC to create or modify Gateway API resources with no business need, potentially leading to the compromise of the confidentiality, integrity, and availability of resources and traffic within the cluster.
+
+ **Threat**: Unauthorised creation or misconfiguration of Gateway API resources by a threat actor with cluster-scoped access.
+
+ **Recommendation**: Configure the apiGroup and resource fields in RBAC policies to restrict access to [Gateway](https://gateway-api.sigs.k8s.io/) and [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resources. Enable namespace isolation by using the namespace field, preventing unauthorised access to gateways in other namespaces.
+
+### EGTM-009 Co-tenant misconfigures resource across namespaces
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-009|EGTM-GW-002|Gateway API|High|
+
+ **Risk**: There is a risk that a co-tenant misconfigures Gateway or Route resources, compromising the confidentiality, integrity, and availability of routed traffic through Envoy Gateway.
+
+ **Threat**: Malicious or accidental co-tenant misconfiguration of Gateways and Routes associated with other application teams.
+
+ **Recommendation**: Dedicated Envoy Gateways should be provided to each tenant within their respective namespace. A one-to-one relationship should be established between GatewayClass and Gateway resources, meaning that each tenant namespace should have their own GatewayClass watched by a unique Envoy Gateway Controller as defined here in the [Deployment Mode](../operations/deployment-mode) documentation.
+
+ Application Admins should have write permissions on the Gateway resource, but only in their specific namespaces, and Application Developers should only hold write permissions on Route resources. To enact this access control schema, follow the [Write Permissions for Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model) described in the Kubernetes Gateway API security model. Examples of secured gateway-route topologies can be found [here](https://gateway-api.sigs.k8s.io/concepts/api-overview/#attaching-routes-to-gateways) within the Kubernetes Gateway API docs.
+
+ Optionally, consider a GitOps model, where only the GitOps operator has the permission to deploy or modify custom resources in production.
+
+### EGTM-014 Malicious image admission
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-014|EGTM-CS-006|Container Security|High|
+
+ **Risk**: There is a risk that a supply chain attack on Envoy Gateway results in an arbitrary compromise of the confidentiality, integrity or availability of tenant data.
+
+ **Threat**: Supply chain threat actor introduces malicious code into Envoy Gateway or Proxy.
+
+ **Recommendation**: The Envoy Gateway project should continue to work towards conformance with supply-chain security best practices throughout the project lifecycle (for example, as set out in the [CNCF Software Supply Chain Best Practices Whitepaper](https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf)). Adherence to [Supply-chain Levels for Software Artefacts](https://slsa.dev/) (SLSA) standards is crucial for maintaining the security of the system. Employ version control systems to monitor the source and build platforms and assign responsibility to a specific stakeholder.
+
+ Integrate a supply chain security tool such as Sigstore, which provides native capabilities for signing and verifying container images and software artefacts. [Software Bill of Materials](https://www.cisa.gov/sbom) (SBOM), [Vulnerability Exploitability eXchange](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf) (VEX), and signed artefacts should also be incorporated into the security protocol.
+
+### EGTM-020 Out of date or misconfigured Envoy Proxy image
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-020|EGTM-CS-009|Container Security|High|
+
+ **Risk**: There is a risk that a threat actor exploits an Envoy Proxy vulnerability to remote code execution (RCE) due to out of date or misconfigured Envoy Proxy pod deployment, compromising the confidentiality and integrity of Envoy Proxy along with the availability of the proxy service.
+
+ **Threat**: Deployment of an Envoy Proxy or Gateway image containing exploitable CVEs.
+
+ **Recommendation**: Always use the latest version of the Envoy Proxy image. Regularly check for updates and patch the system as soon as updates become available. Implement a CI/CD pipeline that includes security checks for images and prevents deployment of insecure configurations. A suitable tool should be chosen to provide container vulnerability scanning to mitigate the risk of known vulnerabilities.
+
+ Utilise the [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) controller to enforce [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and configure the [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) to limit its capabilities per the principle of least privilege.
+
+### EGTM-022 Credentials are stored as Kubernetes Secrets
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-022|EGTM-CS-010|Container Security|High|
+
+ **Risk**: There is a risk that the OIDC client secret (for OIDC authentication) and user password hashes (for basic authentication) get leaked due to misconfigured RBAC permissions.
+
+ **Threat**: Unauthorised access to the application due to credential leakage.
+
+ **Recommendation**: Ensure that only authorised users and service accounts are able to access secrets. This is especially important in namespaces where SecurityPolicy objects are configured, since those namespaces are the ones to store secrets containing the client secret (in OIDC scenarios) and user password hashes (in basic authentication scenarios).
+
+ To do so, minimise the use of ClusterRoles and Roles allowing listing and getting secrets. Perform periodic audits of RBAC permissions.
+
+### EGTM-023 Weak Authentication
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-023|EGTM-EG-007|Envoy Gateway|High|
+
+ **Risk**: There is a risk of unauthorised access due to the use of basic authentication, which does not enforce any password restriction in terms of complexity and length. In addition, password hashes are stored in SHA1 format, which is a deprecated hashing function.
+
+ **Threat**: Unauthorised access to the application due to weak authentication mechanisms.
+
+ **Recommendation**: It is recommended to make use of stronger authentication mechanisms (i.e. JWT authentication and OIDC authentication) instead of basic authentication. These authentication mechanisms have many advantages, such as the use of short-lived credentials and a central management of security policies through the identity provider.
+
+## Medium Priority Findings
+
+### EGTM-008 Misconfiguration of Envoy Gateway static config
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-008|EGTM-EG-003|Envoy Gateway|Medium|
+
+ **Risk**: There is a risk of a threat actor misconfiguring static config and compromising the integrity of Envoy Gateway, ultimately leading to the compromised confidentiality, integrity, or availability of tenant data and cluster resources.
+
+ **Threat**: Accidental or deliberate misconfiguration of static configuration leads to a misconfigured deployment of Envoy Gateway, for example logging parameters could be modified or global rate limiting configuration misconfigured.
+
+ **Recommendation**: Implement a GitOps model, utilising Kubernetes\' Role-Based Access Control (RBAC) and adhering to the principle of least privilege to minimise human intervention on the cluster. For instance, tools like [Flux](https://fluxcd.io/) and [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) can be used for declarative GitOps deployments, ensuring all changes are tracked and reviewed. Additionally, configure your source control management (SCM) system to include mandatory pull request (PR) reviews, commit signing, and protected branches to ensure only authorised changes can be committed to the start-up configuration.
+
+### EGTM-010 Weak pod security contexts and policies
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-010|EGTM-CS-005|Container Security|Medium|
+
+ **Risk**: There is a risk that a threat actor exploits a weak pod security context, compromising the CIA of a node and the resources / services which run on it.
+
+ **Threat**: Threat Actor who has compromised a pod exploits weak security context to escape to a node, potentially leading to the compromise of Envoy Proxy or Gateway running on the same node.
+
+ **Recommendation**: To mitigate this risk, apply [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) at a minimum of [Baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) level to all namespaces, especially those containing Envoy Gateway and Proxy Pods. Pod security standards are implemented through K8s [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) to provide [admission control modes](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces) (enforce, audit, and warn) for namespaces. Pod security standards can be enforced by namespace labels as shown [here](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/), to enforce a baseline level of pod security to specific namespaces.
+
+ Further enhance the security by implementing a sandboxing solution such as [gVisor](https://gvisor.dev/) for Envoy Gateway and Proxy Pods to isolate the application from the host kernel. This can be set within the runtimeClassName of the Pod specification.
+
+### EGTM-012 ClusterRoles and Roles with permission to deploy ReferenceGrants
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|----------------|----------------------|-----------------|
+|EGTM-012|EGTM-GW-004|Gateway API|Medium|
+
+ **Risk**: There is a risk that a threat actor could abuse excessive RBAC privileges to create ReferenceGrant resources. These resources could then be used to create cross-namespace communication, leading to unauthorised access to the application. This could compromise the confidentiality and integrity of resources and configuration in the affected namespaces and potentially disrupt the availability of services that rely on these object references.
+
+ **Threat**: A ReferenceGrant is created, which validates traffic to cross namespace trust boundaries without a valid business reason, such as a route in one tenant\'s namespace referencing a backend in another.
+
+ **Recommendation**: Ensure that the ability to create ReferenceGrant resources is restricted to the minimum number of people. Pay special attention to ClusterRoles that allow that action.
+
+### EGTM-018 Network Denial of Service (DoS)
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|----------------|----------------------|-----------------|
+|EGTM-018|EGTM-GW-006|Gateway API|Medium|
+
+ **Risk**: There is a risk that malicious requests could lead to a Denial of Service (DoS) attack, thereby reducing API gateway availability due to misconfigurations in rate-limiting or load balancing controls, or a lack of route timeout enforcement.
+
+ **Threat**: Reduced API gateway availability due to an attacker\'s maliciously crafted request (e.g., QoD) potentially inducing a Denial of Service (DoS) attack.
+
+ **Recommendation**: To ensure high availability and mitigate potential security threats, follow the guidelines in the Envoy Gateway documentation for configuring [local rate limit](../traffic/local-rate-limit) filters, [global rate limit](../traffic/global-rate-limit) filters, and load balancing.
+
+ Further, adhere to best practices for configuring Envoy Proxy as an edge proxy documented [here](https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge#configuring-envoy-as-an-edge-proxy) within the EnvoyProxy docs. This involves configuring TCP and HTTP proxies with specific settings, including restricting access to the admin endpoint, setting the [overload manager](https://www.envoyproxy.io/docs/envoy/latest/configuration/operations/overload_manager/overload_manager#config-overload-manager) and [listener](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-per-connection-buffer-limit-bytes) / [cluster](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-field-config-cluster-v3-cluster-per-connection-buffer-limit-bytes) buffer limits, enabling [use_remote_address](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-use-remote-address), setting [connection and stream timeouts](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#faq-configuration-timeouts), limiting [maximum concurrent streams](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-max-concurrent-streams), setting [initial stream window size limit](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size), and configuring action on [headers_with_underscores](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-headers-with-underscores-action).
+
+ [Path normalisation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-normalize-path) should be enabled to minimise path confusion vulnerabilities. These measures help protect against volumetric threats such as Denial of Service (DoS) attacks. Utilise custom resources to implement policy attachment, thereby exposing request limit configuration for route types.
+
+### EGTM-019 JWT-based authentication replay attacks
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-019|EGTM-DP-004|Container Security|Medium|
+
+ **Risk**: There is a risk that replay attacks using stolen or reused JSON Web Tokens (JWTs) can compromise transmission integrity, thereby undermining the confidentiality and integrity of the data plane.
+
+ **Threat**: Transmission integrity is compromised due to replay attacks using stolen or reused JSON Web Tokens (JWTs).
+
+ **Recommendation**: Comply with JWT best practices for enhanced security, paying special attention to the use of short-lived tokens, which reduce the window of opportunity for a replay attack. The [exp](https://datatracker.ietf.org/doc/html/rfc7519#page-9) claim can be used to set token expiration times.
+
+### EGTM-024 Excessive privileges via extension policies
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-024|EGTM-EG-008|Envoy Gateway|Medium|
+
+ **Risk**: There is a risk of developers getting more privileges than required due to the use of SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy and BackendTrafficPolicy. These resources can be attached to a Gateway resource. Therefore, a developer with permission to deploy them would be able to modify a Gateway configuration by targeting the gateway in the policy manifest. This conflicts with the [Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model), where developers do not have write permissions on Gateways.
+
+ **Threat**: Excessive developer permissions lead to a misconfiguration and/or unauthorised access.
+
+ **Recommendation**: Considering the Tenant C scenario (represented in the Architecture Diagram), if a developer can create SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy or BackendTrafficPolicy objects in namespace C, they would be able to modify a Gateway configuration by attaching the policy to the gateway. In such scenarios, it is recommended to either:
+
+ a. Create a separate namespace, where developers have no permissions, to host tenant C\'s gateway. Note that, due to design decisions, the SecurityPolicy/EnvoyPatchPolicy/ClientTrafficPolicy/BackendTrafficPolicy object can only target resources deployed in the same namespace. Therefore, having a separate namespace for the gateway would prevent developers from attaching the policy to the gateway.
+
+ b. Forbid the creation of these policies for developers in namespace C.
+
+ On the other hand, in scenarios similar to tenants A and B, where a shared gateway namespace is in place, this issue is more limited. Note that in this scenario, developers don\'t have access to the shared gateway namespace.
+
+ In addition, it is important to mention that EnvoyPatchPolicy resources can also be attached to GatewayClass resources. This means that, in order to comply with the Advanced 4 Tier model, individuals with the Application Administrator role should not have access to this resource either.
+
+## Low Priority Findings
+
+### EGTM-003 Misconfiguration leads to insecure TLS settings
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|--------------|------------------------|-----------------|
+|EGTM-003|EGTM-EG-001|Envoy Gateway|Low|
+
+ **Risk**: There is a risk that a threat actor could downgrade the security of proxied connections by configuring a weak set of cipher suites, compromising the confidentiality and integrity of proxied traffic.
+
+ **Threat**: Exploit weak cipher suite configuration to downgrade security of proxied connections.
+
+ **Recommendation**: Users operating in highly regulated environments may need to tightly control the TLS protocol and associated cipher suites, blocking non-conforming incoming connections to the gateway.
+
+ EnvoyProxy bootstrap config can be customised as per the [customise EnvoyProxy](../operations/customize-envoyproxy) documentation. In addition, from v.1.0.0, it is possible to configure common TLS properties for a Gateway or XRoute through the [ClientTrafficPolicy](https://gateway.envoyproxy.io/latest/api/extension_types/#clienttrafficpolicy) object.
+
+### EGTM-005 Envoy Gateway Helm chart deployment does not set AppArmor and Seccomp profiles
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-005|EGTM-CP-002|Container Security|Low|
+
+ **Risk**: Threat actor who has obtained access to Envoy Gateway pod could exploit the lack of AppArmor and Seccomp profiles in the Envoy Gateway deployment to attempt a container breakout, given the presence of an exploitable vulnerability, potentially impacting the confidentiality and integrity node resources.
+
+ **Threat**: Unauthorised syscalls and malicious code running in the Envoy Gateway pod.
+
+ **Recommendation**: Implement [AppArmor](https://kubernetes.io/docs/tutorials/security/apparmor/) policies by setting \: \ within container.apparmor.security.beta.kubernetes.io (note, this config is set *per container*). Well-defined AppArmor policies may provide greater protection from unknown threats.
+
+ Enforce [Seccomp](https://kubernetes.io/docs/tutorials/security/seccomp/) profiles by setting the seccompProfile under securityContext. Ideally, a [fine-grained](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-with-a-seccomp-profile-that-only-allows-necessary-syscalls) profile should be used to restrict access to only necessary syscalls, however the \--seccomp-default flag can be set to resort to [RuntimeDefault](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-that-uses-the-container-runtime-default-seccomp-profile) which provides a container runtime specific. Example seccomp profiles can be found [here](https://kubernetes.io/docs/tutorials/security/seccomp/#download-profiles).
+
+ To further enhance pod security, consider implementing [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) via seLinuxOptions for additional syscall attack surface reduction. Setting readOnlyRootFilesystem == true enforces an immutable root filesystem, preventing the addition of malicious binaries to the PATH and increasing the attack cost. Together, these configuration items improve the pods [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/).
+
+### EGTM-006 Envoy Proxy pods deployed with a shell enabled
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-006|EGTM-CS-004|Container Security|Low|
+
+ **Risk**: There is a risk that a threat actor exploits a vulnerability in Envoy Proxy to expose a reverse shell, enabling them to compromise the confidentiality, integrity and availability of tenant data via a secondary attack.
+
+ **Threat**: If an external attacker managed to exploit a vulnerability in Envoy, the presence of a shell would be greatly helpful for the attacker in terms of potentially pivoting, escalating, or establishing some form of persistence.
+
+ **Recommendation**: By default, Envoy uses a [distroless](https://github.com/GoogleContainerTools/distroless) image since v.0.6.0, which does not ship a shell. Therefore, ensure EnvoyProxy image is up-to-date and patched with the latest stable version.
+
+ If using private EnvoyProxy images, use a lightweight EnvoyProxy image without a shell or debugging tool(s) which may be useful for an attacker.
+
+ An [AuditPolicy](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#audit-policy) (audit.k8s.io/v1beta1) can be configured to record API calls made within your cluster, allowing for identification of malicious traffic and enabling incident response. Requests are recorded based on stages which delineate between the lifecycle stage of the request made (e.g., RequestReceived, ResponseStarted, & ResponseComplete).
+
+### EGTM-011 Route Bindings on custom labels
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-011|EGTM-GW-003|Gateway API|Low|
+
+ **Risk**: There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.
+
+ **Threat**: If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway.
+
+ **Recommendation**: Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces.
+
+### EGTM-013 GatewayClass namespace validation is not configured
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-013|EGTM-GW-005|Gateway API|Low|
+
+ **Risk**: There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.
+
+ **Threat**: Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.
+
+ **Recommendation**: Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup.
+
+### EGTM-015 ServiceAccount token authentication
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-015|EGTM-CS-007|Container Security|Low|
+
+ **Risk**: There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.
+
+ **Threat**: The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.
+
+ **Recommendation**: Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec.
+
+### EGTM-016 Misconfiguration leads to lack of Envoy Proxy access activity visibility
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-016|EGTM-EG-004|Envoy Gateway|Low|
+
+ **Risk**: There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.
+
+ **Threat**: Threat actors establish persistence and move laterally through the cluster unnoticed.
+
+ **Recommendation**: Configure [access logging](../../../contributions/design/proxy-accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.
+
+ Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR).
+
+### EGTM-017 Misconfiguration leads to lack of Envoy Gateway activity visibility
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-017|EGTM-EG-005|Envoy Gateway|Low|
+
+ **Risk**: There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.
+
+ **Threat**: The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.
+
+ **Recommendation**: Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.
+
+ Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response.
+
+### EGTM-021 Exposed Envoy Proxy admin interface
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|---------------|-----------------------|-----------------|
+|EGTM-021|EGTM-EG-006|Envoy Gateway|Low|
+
+ **Risk**: There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.
+
+ **Threat**: Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely e.g. /quitquitquit).
+
+ **Recommendation**: The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.
+
+ Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks.
+
+### EGTM-025 Envoy Proxy pods deployed running as root user in the container
+
+|**ID**|**UID**|**Category**|**Priority**|
+|--------------|--------------|------------------------|-----------------|
+|EGTM-025|EGTM-CS-011|Container Security|Low|
+
+**Risk**: The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources
+
+ **Threat**: The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries.
+
+ **Recommendation**: By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container.
+
+Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade.
+
+## Appendix
+
+### In Scope Threat Actor Details
+
+|Threat Actor | Capability | Personal Motivation | Envoy Gateway Attack Samples|
+|-|-|-|-|
+|Application Developer | Leverage internal knowledge and personal access to the Envoy Gateway infrastructure to move laterally and transit trust boundaries | Disgruntled / personal grievances.
Financial incentives | Misconfigure XRoute resources to expose internal applications.
Misconfigure SecurityPolicy objects, reducing the security posture of an application.|
+|Application Administrator | Abuse privileged status to disrupt operations and tenant cluster services through Envoy Gateway misconfig | Disgruntled / personal grievances.
Financial incentives | Create malicious routes to internal applications.
Introduce malicious Envoy Proxy images.
Expose the Envoy Proxy Admin interface.|
+|Cluster Operator | Alter application-level deployments by misconfiguring resource dependencies & SCM to introduce vulnerabilities | Disgruntled / personal grievances.
Financial incentives.
Notoriety | Deploy malicious resources to expose internal applications.
Access authentication secrets.
Fall victim to phishing attacks and inadvertently share authentication credentials to cloud infrastructure or Kubernetes clusters.|
+|Vandal: Script Kiddie, Trespasser | Uses publicly available tools and applications (Nmap,Metasploit, CVE PoCs) | Curiosity.
Personal fame through defacement / denial of service of prominent public facing web resources | Small scale DOS.
Exploit public-facing application services such as the bastion host to gain an initial foothold in the environment|
+|Motivated individual: Political activist, Thief, Terrorist | Write tools and exploits required for their means if sufficiently motivated.
Tend to use these in a targeted fashion against specific organisations. May combine publicly available exploits in a targeted fashion. Tamper with open source supply chains | Personal Gain (Political or Ideological) | Phishing, DDOS, exploit known vulnerabilities.
Compromise third-party components such as Helm charts and container images to inject malicious codes to propagate access throughout the environment.|
+|Organised crime: syndicates, state-affiliated groups | Write tools and exploits required for their means.
Tend to use these in a non-targeted fashion, unless motivation is sufficiently high.
Devotes considerable resources, writes exploits, can bribe/coerce, can launch targeted attacks | Ransom.
Mass extraction of PII / credentials / PCI data.
Financial incentives | Social Engineering, phishing, ransomware, coordinated attacks.
Intercept and replay JWT tokens (via MiTM) between tenant user(s) and envoy gateway to modify app configs in-transit|
+
+### Identified Threats by Priority
+
+|ID|UID|Category|Risk|Threat|Priority| Recommendation |
+|-|-|-|-|-|-|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+|EGTM-001|EGTM-GW-001|Gateway API| Self-signed certificates (which do not comply with PKI best practices) could lead to unauthorised access to the private key associated with the certificate used for inbound TLS termination at Envoy Proxy, compromising the confidentiality and integrity of proxied traffic.
| Compromise of the private key associated with the certificate used for inbound TLS terminating at Envoy Proxy.
|High| The Envoy Gateway quickstart demonstrates how to set up a Secure Gateway using an example where a self-signed root certificate is created using openssl. As stated in the Envoy Gateway documentation, this is not a suitable configuration for Production usage. It is recommended that PKI best practices are followed, whereby certificates are signed by an Intermediary CA which sits underneath an organisational \'offline\' Root CA.
PKI best practices should also apply to the management of client certificates when using mTLS. The Envoy Gateway [mTLS](../security/mutual-tls) task shows how to set up client certificates using self-signed certificates. In the same way as gateway certificates and, as mentioned in the documentation, this configuration should not be used in production environments. |
+|EGTM-002|EGTM-CS-001|Container Security| There is a risk that a threat actor could compromise the Kubernetes secret containing the Envoy private key, allowing the attacker to decrypt Envoy Proxy traffic, compromising the confidentiality of proxied traffic.
| Kubernetes secret containing the Envoy private key is compromised and used to decrypt proxied traffic.
|High| Certificate management best practices mandate short-lived key material where practical, meaning that a mechanism for rotation of private keys and certificates is required, along with a way for certificates to be mounted into Envoy containers. If Kubernetes secrets are used, when a certificate expires, the associated secret must be updated, and Envoy containers must be redeployed. Instead of a manual configuration, it is recommended that [cert-manager](https://github.com/cert-manager/cert-manager) is used. |
+|EGTM-004|EGTM-K8-002|Container Security| There is a risk that a threat actor could abuse misconfigured RBAC to access the Envoy Gateway ClusterRole (envoy-gateway-role) and use it to expose all secrets across the cluster, thus compromising the confidentiality and integrity of tenant data.
| Compromised Envoy Gateway or misconfigured ClusterRoleBinding (envoy-gateway-rolebinding) to Envoy Gateway ClusterRole (envoy-gateway-role), provides access to resources and secrets in different namespaces.
|High| Users should be aware that Envoy Gateway uses a ClusterRole (envoy-gateway-role) when deployed via the Helm chart, to allow management of Envoy Proxies across different namespaces. This ClusterRole is powerful and includes the ability to read secrets in namespaces which may not be within the purview of Envoy Gateway.
Kubernetes best-practices involve restriction of ClusterRoleBindings, with the use of RoleBindings where possible to limit access per namespace by specifying the namespace in metadata. Namespace isolation reduces the impact of compromise from cluster-scoped roles. Ideally, fine-grained K8s roles should be created per the principle of least privilege to ensure they have the minimum access necessary for role functions.
The pull request \#[1656](https://github.com/envoyproxy/gateway/pull/1656) introduced the use of Roles and RoleBindings in [namespaced mode](https://gateway.envoyproxy.io/latest/api/extension_types/#kuberneteswatchmode). This feature can be leveraged to reduce the amount of permissions required by the Envoy Gateway. |
+|EGTM-007|EGTM-EG-002|Envoy Gateway| There is a risk that a threat actor could exploit misconfigured Kubernetes RBAC to create or modify Gateway API resources with no business need, potentially leading to the compromise of the confidentiality, integrity, and availability of resources and traffic within the cluster.
| Unauthorised creation or misconfiguration of Gateway API resources by a threat actor with cluster-scoped access.
|High| Configure the apiGroup and resource fields in RBAC policies to restrict access to [Gateway](https://gateway-api.sigs.k8s.io/) and [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resources. Enable namespace isolation by using the namespace field, preventing unauthorised access to gateways in other namespaces. |
+|EGTM-009|EGTM-GW-002|Gateway API| There is a risk that a co-tenant misconfigures Gateway or Route resources, compromising the confidentiality, integrity, and availability of routed traffic through Envoy Gateway.
| Malicious or accidental co-tenant misconfiguration of Gateways and Routes associated with other application teams.
|High| Dedicated Envoy Gateways should be provided to each tenant within their respective namespace. A one-to-one relationship should be established between GatewayClass and Gateway resources, meaning that each tenant namespace should have their own GatewayClass watched by a unique Envoy Gateway Controller as defined here in the [Deployment Mode](../operations/deployment-mode) documentation.
Application Admins should have write permissions on the Gateway resource, but only in their specific namespaces, and Application Developers should only hold write permissions on Route resources. To enact this access control schema, follow the [Write Permissions for Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model) described in the Kubernetes Gateway API security model. Examples of secured gateway-route topologies can be found [here](https://gateway-api.sigs.k8s.io/concepts/api-overview/#attaching-routes-to-gateways) within the Kubernetes Gateway API docs.
Optionally, consider a GitOps model, where only the GitOps operator has the permission to deploy or modify custom resources in production. |
+|EGTM-014|EGTM-CS-006|Container Security| There is a risk that a supply chain attack on Envoy Gateway results in an arbitrary compromise of the confidentiality, integrity or availability of tenant data.
| Supply chain threat actor introduces malicious code into Envoy Gateway or Proxy.
|High| The Envoy Gateway project should continue to work towards conformance with supply-chain security best practices throughout the project lifecycle (for example, as set out in the [CNCF Software Supply Chain Best Practices Whitepaper](https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf). Adherence to [Supply-chain Levels for Software Artefacts](https://slsa.dev/) (SLSA) standards is crucial for maintaining the security of the system. Employ version control systems to monitor the source and build platforms and assign responsibility to a specific stakeholder.
Integrate a supply chain security tool such as Sigstore, which provides native capabilities for signing and verifying container images and software artefacts. [Software Bill of Materials](https://www.cisa.gov/sbom) (SBOM), [Vulnerability Exploitability eXchange](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf) (VEX), and signed artefacts should also be incorporated into the security protocol. |
+|EGTM-020|EGTM-CS-009|Container Security| There is a risk that a threat actor exploits an Envoy Proxy vulnerability to remote code execution (RCE) due to out of date or misconfigured Envoy Proxy pod deployment, compromising the confidentiality and integrity of Envoy Proxy along with the availability of the proxy service.
| Deployment of an Envoy Proxy or Gateway image containing exploitable CVEs.
|High| Always use the latest version of the Envoy Proxy image. Regularly check for updates and patch the system as soon as updates become available. Implement a CI/CD pipeline that includes security checks for images and prevents deployment of insecure configurations. A tool such as Snyk can be used to provide container vulnerability scanning to mitigate the risk of known vulnerabilities.
Utilise the [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) controller to enforce [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and configure the [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) to limit its capabilities per the principle of least privilege. |
+|EGTM-022|EGTM-CS-010|Container Security| There is a risk that the OIDC client secret (for OIDC authentication) and user password hashes (for basic authentication) get leaked due to misconfigured RBAC permissions.
| Unauthorised access to the application due to credential leakage.
|High| Ensure that only authorised users and service accounts are able to access secrets. This is especially important in namespaces where SecurityPolicy objects are configured, since those namespaces are the ones to store secrets containing the client secret (in OIDC scenarios) and user password hashes (in basic authentication scenarios).
To do so, minimise the use of ClusterRoles and Roles allowing listing and getting secrets. Perform periodic audits of RBAC permissions. |
+|EGTM-023|EGTM-EG-007|Envoy Gateway| There is a risk of unauthorised access due to the use of basic authentication, which does not enforce any password restriction in terms of complexity and length. In addition, password hashes are stored in SHA1 format, which is a deprecated hashing function.
| Unauthorised access to the application due to weak authentication mechanisms.
|High| It is recommended to make use of stronger authentication mechanisms (i.e. JWT authentication and OIDC authentication) instead of basic authentication. These authentication mechanisms have many advantages, such as the use of short-lived credentials and a central management of security policies through the identity provider. |
+|EGTM-008|EGTM-EG-003|Envoy Gateway| There is a risk of a threat actor misconfiguring static config and compromising the integrity of Envoy Gateway, ultimately leading to the compromised confidentiality, integrity, or availability of tenant data and cluster resources.
| Accidental or deliberate misconfiguration of static configuration leads to a misconfigured deployment of Envoy Gateway, for example logging parameters could be modified or global rate limiting configuration misconfigured.
|Medium| Implement a GitOps model, utilising Kubernetes\' Role-Based Access Control (RBAC) and adhering to the principle of least privilege to minimise human intervention on the cluster. For instance, tools like [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) can be used for declarative GitOps deployments, ensuring all changes are tracked and reviewed. Additionally, configure your source control management (SCM) system to include mandatory pull request (PR) reviews, commit signing, and protected branches to ensure only authorised changes can be committed to the start-up configuration. |
+|EGTM-010|EGTM-CS-005|Container Security| There is a risk that a threat actor exploits a weak pod security context, compromising the CIA of a node and the resources / services which run on it.
| Threat Actor who has compromised a pod exploits weak security context to escape to a node, potentially leading to the compromise of Envoy Proxy or Gateway running on the same node.
|Medium| To mitigate this risk, apply [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) at a minimum of [Baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) level to all namespaces, especially those containing Envoy Gateway and Proxy Pods. Pod security standards are implemented through K8s [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) to provide [admission control modes](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces) (enforce, audit, and warn) for namespaces. Pod security standards can be enforced by namespace labels as shown [here](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/), to enforce a baseline level of pod security to specific namespaces.
Further enhance the security by implementing a sandboxing solution such as [gVisor](https://gvisor.dev/) for Envoy Gateway and Proxy Pods to isolate the application from the host kernel. This can be set within the runtimeClassName of the Pod specification. |
+|EGTM-012|EGTM-GW-004|Gateway API| There is a risk that a threat actor could abuse excessive RBAC privileges to create ReferenceGrant resources. These resources could then be used to create cross-namespace communication, leading to unauthorised access to the application. This could compromise the confidentiality and integrity of resources and configuration in the affected namespaces and potentially disrupt the availability of services that rely on these object references.
| A ReferenceGrant is created, which validates traffic to cross namespace trust boundaries without a valid business reason, such as a route in one tenant\'s namespace referencing a backend in another.
|Medium| Ensure that the ability to create ReferenceGrant resources is restricted to the minimum number of people. Pay special attention to ClusterRoles that allow that action. |
+|EGTM-018|EGTM-GW-006|Gateway API| There is a risk that malicious requests could lead to a Denial of Service (DoS) attack, thereby reducing API gateway availability due to misconfigurations in rate-limiting or load balancing controls, or a lack of route timeout enforcement.
| Reduced API gateway availability due to an attacker\'s maliciously crafted request (e.g., QoD) potentially inducing a Denial of Service (DoS) attack.
|Medium| To ensure high availability and to mitigate potential security threats, adhere to the Envoy Gateway documentation for the configuration of a [rate-limiting](../traffic/global-rate-limit) filter and load balancing.
Further, adhere to best practices for configuring Envoy Proxy as an edge proxy documented [here](https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge#configuring-envoy-as-an-edge-proxy) within the EnvoyProxy docs. This involves configuring TCP and HTTP proxies with specific settings, including restricting access to the admin endpoint, setting the [overload manager](https://www.envoyproxy.io/docs/envoy/latest/configuration/operations/overload_manager/overload_manager#config-overload-manager) and [listener](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-per-connection-buffer-limit-bytes) / [cluster](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-field-config-cluster-v3-cluster-per-connection-buffer-limit-bytes) buffer limits, enabling [use_remote_address](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-use-remote-address), setting [connection and stream timeouts](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#faq-configuration-timeouts), limiting [maximum concurrent streams](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-max-concurrent-streams), setting [initial stream window size limit](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size), and configuring action on [headers_with_underscores](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-headers-with-underscores-action).
[Path normalisation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-normalize-path) should be enabled to minimise path confusion vulnerabilities. These measures help protect against volumetric threats such as Denial of Service (DoS)nattacks. Utilise custom resources to implement policy attachment, thereby exposing request limit configuration for route types. |
+|EGTM-019|EGTM-DP-004|Container Security| There is a risk that replay attacks using stolen or reused JSON Web Tokens (JWTs) can compromise transmission integrity, thereby undermining the confidentiality and integrity of the data plane.
| Transmission integrity is compromised due to replay attacks using stolen or reused JSON Web Tokens (JWTs).
|Medium| Comply with JWT best practices for enhanced security, paying special attention to the use of short-lived tokens, which reduce the window of opportunity for a replay attack. The [exp](https://datatracker.ietf.org/doc/html/rfc7519#page-9) claim can be used to set token expiration times. |
+|EGTM-024|EGTM-EG-008|Envoy Gateway| There is a risk of developers getting more privileges than required due to the use of SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy and BackendTrafficPolicy. These resources can be attached to a Gateway resource. Therefore, a developer with permission to deploy them would be able to modify a Gateway configuration by targeting the gateway in the policy manifest. This conflicts with the [Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model), where developers do not have write permissions on Gateways.
| Excessive developer permissions lead to a misconfiguration and/or unauthorised access.
|Medium| Considering the Tenant C scenario (represented in the Architecture Diagram), if a developer can create SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy or BackendTrafficPolicy objects in namespace C, they would be able to modify a Gateway configuration by attaching the policy to the gateway. In such scenarios, it is recommended to either:
a. Create a separate namespace, where developers have no permissions, > to host tenant C\'s gateway. Note that, due to design decisions, > the > SecurityPolicy/EnvoyPatchPolicy/ClientTrafficPolicy/BackendTrafficPolicy > object can only target resources deployed in the same namespace. > Therefore, having a separate namespace for the gateway would > prevent developers from attaching the policy to the gateway.
b. Forbid the creation of these policies for developers in namespace C.
On the other hand, in scenarios similar to tenants A and B, where a shared gateway namespace is in place, this issue is more limited. Note that in this scenario, developers don\'t have access to the shared gateway namespace.
In addition, it is important to mention that EnvoyPatchPolicy resources can also be attached to GatewayClass resources. This means that, in order to comply with the Advanced 4 Tier model, individuals with the Application Administrator role should not have access to this resource either. |
+|EGTM-003|EGTM-EG-001|Envoy Gateway| There is a risk that a threat actor could downgrade the security of proxied connections by configuring a weak set of cipher suites, compromising the confidentiality and integrity of proxied traffic.
| Exploit weak cipher suite configuration to downgrade security of proxied connections.
|Low| Users operating in highly regulated environments may need to tightly control the TLS protocol and associated cipher suites, blocking non-conforming incoming connections to the gateway.
EnvoyProxy bootstrap config can be customised as per the [customise EnvoyProxy](../operations/customize-envoyproxy) documentation. In addition, from v.1.0.0, it is possible to configure common TLS properties for a Gateway or XRoute through the [ClientTrafficPolicy](https://gateway.envoyproxy.io/latest/api/extension_types/#clienttrafficpolicy) object. |
+|EGTM-005|EGTM-CP-002|Container Security| Threat actor who has obtained access to Envoy Gateway pod could exploit the lack of AppArmor and Seccomp profiles in the Envoy Gateway deployment to attempt a container breakout, given the presence of an exploitable vulnerability, potentially impacting the confidentiality and integrity of namespace resources.
| Unauthorised syscalls and malicious code running in the Envoy Gateway pod.
|Low| Implement [AppArmor](https://kubernetes.io/docs/tutorials/security/apparmor/) policies by setting \: \ within container.apparmor.security.beta.kubernetes.io (note, this config is set *per container*). Well-defined AppArmor policies may provide greater protection from unknown threats.
Enforce [Seccomp](https://kubernetes.io/docs/tutorials/security/seccomp/) profiles by setting the seccompProfile under securityContext. Ideally, a [fine-grained](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-with-a-seccomp-profile-that-only-allows-necessary-syscalls) profile should be used to restrict access to only necessary syscalls, however the \--seccomp-default flag can be set to resort to [RuntimeDefault](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-that-uses-the-container-runtime-default-seccomp-profile) which provides a container runtime specific. Example seccomp profiles can be found [here](https://kubernetes.io/docs/tutorials/security/seccomp/#download-profiles).
To further enhance pod security, consider implementing [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) via seLinuxOptions for additional syscall attack surface reduction. Setting readOnlyRootFilesystem == true enforces an immutable root filesystem, preventing the addition of malicious binaries to the PATH and increasing the attack cost. Together, these configuration items improve the pods [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). |
+|EGTM-006|EGTM-CS-004|Container Security| There is a risk that a threat actor exploits a vulnerability in Envoy Proxy to expose a reverse shell, enabling them to compromise the confidentiality, integrity and availability of tenant data via a secondary attack.
| If an external attacker managed to exploit a vulnerability in Envoy, the presence of a shell would be greatly helpful for the attacker in terms of potentially pivoting, escalating, or establishing some form of persistence.
|Low| By default, Envoy uses a [distroless](https://github.com/GoogleContainerTools/distroless) image since v.0.6.0, which does not ship a shell. Therefore, ensure EnvoyProxy image is up-to-date and patched with the latest stable version.
If using private EnvoyProxy images, use a lightweight EnvoyProxy image without a shell or debugging tool(s) which may be useful for an attacker.
An [AuditPolicy](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#audit-policy) (audit.k8s.io/v1beta1) can be configured to record API calls made within your cluster, allowing for identification of malicious traffic and enabling incident response. Requests are recorded based on stages which delineate between the lifecycle stage of the request made (e.g., RequestReceived, ResponseStarted, & ResponseComplete). |
+|EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.
| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway
|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces. |
+|EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.
| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.
|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup. |
+|EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.
| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.
|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec. |
+|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.
| Threat actors establish persistence and move laterally through the cluster unnoticed.
|Low| Configure [access logging](../../../contributions/design/proxy-accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.
Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). |
+|EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.
| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.
|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.
Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response. |
+|EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.
| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).
|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.
Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks. |
+|EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade. |
+
+
+## Attack Trees
+
+Attack trees offer a methodical way of describing the security of systems, based on varying attack patterns. It's important to approach the review of attack trees from a top-down perspective. The top node, also known as the root node, symbolises the attacker's primary objective. This goal is then broken down into subsidiary aims, each reflecting a different strategy to attain the root objective. This deconstruction persists until reaching the lowest level objectives or 'leaf nodes', which depict attacks that can be directly launched.
+
+It is essential to note that attack trees presented here are speculative paths for potential exploitation. The Envoy Gateway project is in a continuous development cycle, and as the project evolves, new vulnerabilities may be exposed, or additional controls could be introduced. Therefore, the threats illustrated in the attack trees should be perceived as point-in-time reflections of the project’s current state at the time of writing this threat model.
+
+### Node ID Schema
+
+Each node in the attack tree is assigned a unique identifier following the AT#-## schema. This allows easy reference to specific nodes in the attack trees throughout the threat model. The first part of the ID (AT#) signifies the attack tree number, while the second part (##) represents the node number within that tree.
+
+### Logical Operators
+
+Logical AND/OR operators are used to represent the relationship between parent and child nodes. An AND operator means that all child nodes must be achieved to satisfy the parent node. An OR operator between a parent node and its child nodes means that any of the child nodes can be achieved to satisfy the parent node.
+
+### Attack Tree Node Legend
+
+![AT Legend](/img/AT-legend.png)
+
+### AT0
+
+![AT0](/img/AT0.png)
+
+### AT1
+
+![AT1](/img/AT1.png)
+
+### AT2
+
+![AT2](/img/AT2.png)
+
+### AT3
+
+![AT3](/img/AT3.png)
+
+### AT4
+
+![AT4](/img/AT4.png)
+
+### AT5
+
+![AT5](/img/AT5.png)
+
+### AT6
+
+![AT6](/img/AT6.png)
diff --git a/site/content/en/v1.2/tasks/security/tls-cert-manager.md b/site/content/en/v1.2/tasks/security/tls-cert-manager.md
new file mode 100644
index 00000000000..61ebb5c0162
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/tls-cert-manager.md
@@ -0,0 +1,435 @@
+---
+title: "Using cert-manager For TLS Termination"
+---
+
+This task shows how to set up [cert-manager](https://cert-manager.io/) to automatically create certificates and secrets for use by Envoy Gateway.
+It will first show how to enable the self-sign issuer, which is useful to test that cert-manager and Envoy Gateway can talk to each other.
+Then it shows how to use [Let's Encrypt's staging environment](https://letsencrypt.org/docs/staging-environment/).
+Changing to the Let's Encrypt production environment is straight-forward after that.
+
+## Prerequisites
+
+* A Kubernetes cluster and a configured `kubectl`.
+* The `helm` command.
+* The `curl` command or similar for testing HTTPS requests.
+* For the ACME HTTP-01 challenge to work
+ * your Gateway must be reachable on the public Internet.
+ * the domain name you use (we use `www.example.com`) must point to the Gateway's external IP(s).
+
+## Installation
+
+{{< boilerplate prerequisites >}}
+
+## Deploying cert-manager
+
+*This is a summary of [cert-manager Installation with Helm](https://cert-manager.io/docs/installation/helm/).*
+
+Installing cert-manager is straight-forward, but currently (v1.12) requires setting a feature gate to enable the Gateway API support.
+
+```console
+$ helm repo add jetstack https://charts.jetstack.io
+$ helm upgrade --install --create-namespace --namespace cert-manager --set installCRDs=true --set featureGates=ExperimentalGatewayAPISupport=true cert-manager jetstack/cert-manager
+```
+
+You should now have `cert-manager` running with nothing to do:
+
+```console
+$ kubectl wait --for=condition=Available deployment -n cert-manager --all
+deployment.apps/cert-manager condition met
+deployment.apps/cert-manager-cainjector condition met
+deployment.apps/cert-manager-webhook condition met
+
+$ kubectl get -n cert-manager deployment
+NAME READY UP-TO-DATE AVAILABLE AGE
+cert-manager 1/1 1 1 42m
+cert-manager-cainjector 1/1 1 1 42m
+cert-manager-webhook 1/1 1 1 42m
+```
+
+## A Self-Signing Issuer
+
+cert-manager can have any number of *issuer* configurations.
+The simplest issuer type is [SelfSigned](https://cert-manager.io/docs/configuration/selfsigned/).
+It simply takes the certificate request and signs it with the private key it generates for the TLS Secret.
+
+```
+Self-signed certificates don't provide any help in establishing trust between certificates.
+However, they are great for initial testing, due to their simplicity.
+```
+
+To install self-signing, run
+
+```console
+$ kubectl apply -f - <}}
+
+## TLS Certificates
+
+Generate the certificates and keys used by the Service to terminate client TLS connections.
+For the application, we'll deploy a sample echoserver app, with the certificates loaded in the application Pod.
+
+__Note:__ These certificates will not be used by the Gateway, but will remain in the application scope.
+
+Create a root certificate and private key to sign certificates:
+
+```shell
+openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
+```
+
+Create a certificate and a private key for `passthrough.example.com`:
+
+```shell
+openssl req -out passthrough.example.com.csr -newkey rsa:2048 -nodes -keyout passthrough.example.com.key -subj "/CN=passthrough.example.com/O=some organization"
+openssl x509 -req -sha256 -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in passthrough.example.com.csr -out passthrough.example.com.crt
+```
+
+Store the cert/keys in A Secret:
+
+```shell
+kubectl create secret tls server-certs --key=passthrough.example.com.key --cert=passthrough.example.com.crt
+```
+
+## Deployment
+
+Deploy TLS Passthrough application Deployment, Service and TLSRoute:
+
+```shell
+kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/tls-passthrough.yaml
+```
+
+Patch the Gateway from the Quickstart to include a TLS listener that listens on port `6443` and is configured for
+TLS mode Passthrough:
+
+```shell
+kubectl patch gateway eg --type=json --patch '
+ - op: add
+ path: /spec/listeners/-
+ value:
+ name: tls
+ protocol: TLS
+ hostname: passthrough.example.com
+ port: 6443
+ tls:
+ mode: Passthrough
+ '
+```
+
+## Testing
+
+{{< tabpane text=true >}}
+{{% tab header="With External LoadBalancer Support" %}}
+
+You can also test the same functionality by sending traffic to the External IP of the Gateway:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+Curl the example app through the Gateway, e.g. Envoy proxy:
+
+```shell
+curl -v -HHost:passthrough.example.com --resolve "passthrough.example.com:6443:${GATEWAY_HOST}" \
+--cacert example.com.crt https://passthrough.example.com:6443/get
+```
+
+{{% /tab %}}
+{{% tab header="Without LoadBalancer Support" %}}
+
+Get the name of the Envoy service created the by the example Gateway:
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+```
+
+Port forward to the Envoy service:
+
+```shell
+kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 6043:6443 &
+```
+
+Curl the example app through Envoy proxy:
+
+```shell
+curl -v --resolve "passthrough.example.com:6043:127.0.0.1" https://passthrough.example.com:6043 \
+--cacert passthrough.example.com.crt
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the Secret:
+
+```shell
+kubectl delete secret/server-certs
+```
+
+## Next Steps
+
+Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project.
diff --git a/site/content/en/v1.2/tasks/security/tls-termination.md b/site/content/en/v1.2/tasks/security/tls-termination.md
new file mode 100644
index 00000000000..1100b04699f
--- /dev/null
+++ b/site/content/en/v1.2/tasks/security/tls-termination.md
@@ -0,0 +1,92 @@
+---
+title: "TLS Termination for TCP"
+---
+
+This task will walk through the steps required to configure TLS Terminate mode for TCP traffic via Envoy Gateway.
+This task uses a self-signed CA, so it should be used for testing and demonstration purposes only.
+
+## Prerequisites
+
+- OpenSSL to generate TLS assets.
+
+## Installation
+
+{{< boilerplate prerequisites >}}
+
+## TLS Certificates
+
+Generate the certificates and keys used by the Gateway to terminate client TLS connections.
+
+Create a root certificate and private key to sign certificates:
+
+```shell
+openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
+```
+
+Create a certificate and a private key for `www.example.com`:
+
+```shell
+openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization"
+openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt
+```
+
+Store the cert/key in a Secret:
+
+```shell
+kubectl create secret tls example-cert --key=www.example.com.key --cert=www.example.com.crt
+```
+
+Install the TLS Termination for TCP example resources:
+
+```shell
+kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/tls-termination.yaml
+```
+
+Verify the Gateway status:
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+## Testing
+
+{{< tabpane text=true >}}
+{{% tab header="With External LoadBalancer Support" %}}
+
+Get the External IP of the Gateway:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+Query the example app through the Gateway:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \
+--cacert example.com.crt https://www.example.com/get
+```
+
+{{% /tab %}}
+{{% tab header="Without LoadBalancer Support" %}}
+
+Get the name of the Envoy service created the by the example Gateway:
+
+```shell
+export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
+```
+
+Port forward to the Envoy service:
+
+```shell
+kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443 &
+```
+
+Query the example app through Envoy proxy:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \
+--cacert example.com.crt https://www.example.com:8443/get
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
diff --git a/site/content/en/v1.2/tasks/traffic/_index.md b/site/content/en/v1.2/tasks/traffic/_index.md
new file mode 100644
index 00000000000..f884ccdfcb0
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Traffic"
+weight: 1
+description: This section includes Traffic Management tasks.
+---
diff --git a/site/content/en/v1.2/tasks/traffic/backend.md b/site/content/en/v1.2/tasks/traffic/backend.md
new file mode 100644
index 00000000000..55d125a27ad
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/backend.md
@@ -0,0 +1,210 @@
+---
+title: "Backend Routing"
+---
+
+Envoy Gateway supports routing to native K8s resources such as `Service` and `ServiceImport`. The `Backend` API is a custom Envoy Gateway [extension resource][] that can used in Gateway-API [BackendObjectReference][].
+
+## Motivation
+The Backend API was added to support several use cases:
+- Allowing users to integrate Envoy with services (Ext Auth, Rate Limit, ALS, ...) using Unix Domain Sockets, which are currently not supported by K8s.
+- Simplify [routing to cluster-external backends][], which currently requires users to maintain both K8s `Service` and `EndpointSlice` resources.
+
+## Warning
+
+Similar to the K8s EndpointSlice API, the Backend API can be misused to allow traffic to be sent to otherwise restricted destinations, as described in [CVE-2021-25740][].
+A Backend resource can be used to:
+- Expose a Service or Pod that should not be accessible
+- Reference a Service or Pod by a Route without appropriate Reference Grants
+- Expose the Envoy Proxy localhost (including the Envoy admin endpoint)
+
+For these reasons, the Backend API is disabled by default in Envoy Gateway configuration. Envoy Gateway admins are advised to follow [upstream recommendations][] and restrict access to the Backend API using K8s RBAC.
+
+## Restrictions
+
+The Backend API is currently supported only in the following BackendReferences:
+- [HTTPRoute]: IP and FQDN endpoints
+- [TLSRoute]: IP and FQDN endpoints
+- [Envoy Extension Policy] (ExtProc): IP, FQDN and unix domain socket endpoints
+- [Security Policy]: IP and FQDN endpoints for the OIDC providers
+
+The Backend API supports attachment the following policies:
+- [Backend TLS Policy][]
+
+Certain restrictions apply on the value of hostnames and addresses. For example, the loopback IP address range and the localhost hostname are forbidden.
+
+Envoy Gateway does not manage the lifecycle of unix domain sockets referenced by the Backend resource. Envoy Gateway admins are responsible for creating and mounting the sockets into the envoy proxy pod. The latter can be achieved by patching the envoy deployment using the [EnvoyProxy][] resource.
+
+## Quickstart
+
+### Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+### Enable Backend
+
+* By default [Backend][] is disabled. Lets enable it in the [EnvoyGateway][] startup configuration
+
+* The default installation of Envoy Gateway installs a default [EnvoyGateway][] configuration and attaches it
+ using a `ConfigMap`. In the next step, we will update this resource to enable Backend.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{< boilerplate rollout-envoy-gateway >}}
+
+## Testing
+
+### Route to External Backend
+
+* In the following example, we will create a `Backend` resource that routes to httpbin.org:80 and a `HTTPRoute` that references this backend.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Get the Gateway address:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+Send a request and view the response:
+
+```shell
+curl -I -HHost:www.example.com http://${GATEWAY_HOST}/headers
+```
+
+[Backend]: ../../../api/extension_types#backend
+[routing to cluster-external backends]: ./../../tasks/traffic/routing-outside-kubernetes.md
+[BackendObjectReference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.BackendObjectReference
+[extension resource]: https://gateway-api.sigs.k8s.io/guides/migrating-from-ingress/#approach-to-extensibility
+[CVE-2021-25740]: https://nvd.nist.gov/vuln/detail/CVE-2021-25740
+[upstream recommendations]: https://github.com/kubernetes/kubernetes/issues/103675
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[TLSRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute
+[Envoy Extension Policy]: ../../../api/extension_types#envoyextensionpolicy
+[Security Policy]: ../../../api/extension_types#oidcprovider
+[Backend TLS Policy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
+[EnvoyProxy]: ../../../api/extension_types#envoyproxy
+[EnvoyGateway]: ../../../api/extension_types#envoygateway
diff --git a/site/content/en/v1.2/tasks/traffic/circuit-breaker.md b/site/content/en/v1.2/tasks/traffic/circuit-breaker.md
new file mode 100644
index 00000000000..6a359c5e0dc
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/circuit-breaker.md
@@ -0,0 +1,149 @@
+---
+title: "Circuit Breakers"
+---
+
+[Envoy circuit breakers] can be used to fail quickly and apply back-pressure in response to upstream service degradation.
+
+Envoy Gateway supports the following circuit breaker thresholds:
+- **Concurrent Connections**: limit the connections that Envoy can establish to the upstream service. When this threshold is met, new connections will not be established, and some requests will be queued until an existing connection becomes available.
+- **Concurrent Requests**: limit on concurrent requests in-flight from Envoy to the upstream service. When this threshold is met, requests will be queued.
+- **Pending Requests**: limit the pending request queue size. When this threshold is met, overflowing requests will be terminated with a `503` status code.
+
+Envoy's circuit breakers are distributed: counters are not synchronized across different Envoy processes. The default Envoy and Envoy Gateway circuit breaker threshold values (1024) may be too strict for high-throughput systems.
+
+Envoy Gateway introduces a new CRD called [BackendTrafficPolicy][] that allows the user to describe their desired circuit breaker thresholds.
+This instantiated resource can be linked to a [Gateway][], [HTTPRoute][] or [GRPCRoute][] resource.
+
+**Note**: There are distinct circuit breaker counters for each `BackendReference` in an `xRoute` rule. Even if a `BackendTrafficPolicy` targets a `Gateway`, each `BackendReference` in that gateway still has separate circuit breaker counter.
+
+## Prerequisites
+
+### Install Envoy Gateway
+
+{{< boilerplate prerequisites >}}
+
+### Install the hey load testing tool
+
+* The `hey` CLI will be used to generate load and measure response times. Follow the installation instruction from the [Hey project] docs.
+
+## Test and customize circuit breaker settings
+
+This example will simulate a degraded backend that responds within 10 seconds by adding the `?delay=10s` query parameter to API calls. The hey tool will be used to generate 100 concurrent requests.
+
+```shell
+hey -n 100 -c 100 -host "www.example.com" http://${GATEWAY_HOST}/?delay=10s
+```
+
+```console
+Summary:
+ Total: 10.3426 secs
+ Slowest: 10.3420 secs
+ Fastest: 10.0664 secs
+ Average: 10.2145 secs
+ Requests/sec: 9.6687
+
+ Total data: 36600 bytes
+ Size/request: 366 bytes
+
+Response time histogram:
+ 10.066 [1] |■■■■
+ 10.094 [4] |■■■■■■■■■■■■■■■
+ 10.122 [9] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 10.149 [10] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 10.177 [10] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 10.204 [11] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 10.232 [11] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 10.259 [11] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 10.287 [11] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 10.314 [11] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 10.342 [11] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+```
+
+The default circuit breaker threshold (1024) is not met. As a result, requests do not overflow: all requests are proxied upstream and both Envoy and clients wait for 10s.
+
+In order to fail fast, apply a `BackendTrafficPolicy` that limits concurrent requests to 10 and pending requests to 0.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Execute the load simulation again.
+
+```shell
+hey -n 100 -c 100 -host "www.example.com" http://${GATEWAY_HOST}/?delay=10s
+```
+
+```console
+Summary:
+ Total: 10.1230 secs
+ Slowest: 10.1224 secs
+ Fastest: 0.0529 secs
+ Average: 1.0677 secs
+ Requests/sec: 9.8785
+
+ Total data: 10940 bytes
+ Size/request: 109 bytes
+
+Response time histogram:
+ 0.053 [1] |
+ 1.060 [89] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 2.067 [0] |
+ 3.074 [0] |
+ 4.081 [0] |
+ 5.088 [0] |
+ 6.095 [0] |
+ 7.102 [0] |
+ 8.109 [0] |
+ 9.115 [0] |
+ 10.122 [10] |■■■■
+```
+
+With the new circuit breaker settings, and due to the slowness of the backend, only the first 10 concurrent requests were proxied, while the other 90 overflowed.
+* Overflowing Requests failed fast, reducing proxy resource consumption.
+* Upstream traffic was limited, alleviating the pressure on the degraded service.
+
+[Envoy Circuit Breakers]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/circuit_breaking
+[BackendTrafficPolicy]: ../../../api/extension_types#backendtrafficpolicy
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway/
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/
+[GRPCRoute]: https://gateway-api.sigs.k8s.io/api-types/grpcroute/
+[Hey project]: https://github.com/rakyll/hey
diff --git a/site/content/en/v1.2/tasks/traffic/client-traffic-policy.md b/site/content/en/v1.2/tasks/traffic/client-traffic-policy.md
new file mode 100644
index 00000000000..2099ea13685
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/client-traffic-policy.md
@@ -0,0 +1,680 @@
+---
+title: "Client Traffic Policy"
+---
+
+This task explains the usage of the [ClientTrafficPolicy][] API.
+
+## Introduction
+
+The [ClientTrafficPolicy][] API allows system administrators to configure
+the behavior for how the Envoy Proxy server behaves with downstream clients.
+
+## Motivation
+
+This API was added as a new policy attachment resource that can be applied to Gateway resources and it is meant to hold settings for configuring behavior of the connection between the downstream client and Envoy Proxy listener. It is the counterpart to the [BackendTrafficPolicy][] API resource.
+
+## Quickstart
+
+### Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+### Support TCP keepalive for downstream client
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify that ClientTrafficPolicy is Accepted:
+
+```shell
+kubectl get clienttrafficpolicies.gateway.envoyproxy.io -n default
+```
+
+You should see the policy marked as accepted like this:
+
+```shell
+NAME STATUS AGE
+enable-tcp-keepalive-policy Accepted 5s
+```
+
+Curl the example app through Envoy proxy once again:
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get --next --header "Host: www.example.com" http://$GATEWAY_HOST/get
+```
+
+You should see the output like this:
+
+```shell
+* Trying 172.18.255.202:80...
+* Connected to 172.18.255.202 (172.18.255.202) port 80 (#0)
+> GET /get HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.1.2
+> Accept: */*
+>
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< date: Fri, 01 Dec 2023 10:17:04 GMT
+< content-length: 507
+< x-envoy-upstream-service-time: 0
+< server: envoy
+<
+{
+ "path": "/get",
+ "host": "www.example.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/8.1.2"
+ ],
+ "X-Envoy-Expected-Rq-Timeout-Ms": [
+ "15000"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "172.18.0.2"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "4d0d33e8-d611-41f0-9da0-6458eec20fa5"
+ ]
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-58d58f745-2zwvn"
+* Connection #0 to host 172.18.255.202 left intact
+}* Found bundle for host: 0x7fb9f5204ea0 [serially]
+* Can not multiplex, even if we wanted to
+* Re-using existing connection #0 with host 172.18.255.202
+> GET /headers HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.1.2
+> Accept: */*
+>
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< date: Fri, 01 Dec 2023 10:17:04 GMT
+< content-length: 511
+< x-envoy-upstream-service-time: 0
+< server: envoy
+<
+{
+ "path": "/headers",
+ "host": "www.example.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/8.1.2"
+ ],
+ "X-Envoy-Expected-Rq-Timeout-Ms": [
+ "15000"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "172.18.0.2"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "9a8874c0-c117-481c-9b04-933571732ca5"
+ ]
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-58d58f745-2zwvn"
+* Connection #0 to host 172.18.255.202 left intact
+}
+```
+
+You can see keepalive connection marked by the output in:
+
+```shell
+* Connection #0 to host 172.18.255.202 left intact
+* Re-using existing connection #0 with host 172.18.255.202
+```
+
+### Enable Proxy Protocol for downstream client
+
+This example configures Proxy Protocol for downstream clients.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify that ClientTrafficPolicy is Accepted:
+
+```shell
+kubectl get clienttrafficpolicies.gateway.envoyproxy.io -n default
+```
+
+You should see the policy marked as accepted like this:
+
+```shell
+NAME STATUS AGE
+enable-proxy-protocol-policy Accepted 5s
+```
+
+Try the endpoint without using PROXY protocol with curl:
+
+```shell
+curl -v --header "Host: www.example.com" http://$GATEWAY_HOST/get
+```
+
+```shell
+* Trying 172.18.255.202:80...
+* Connected to 172.18.255.202 (172.18.255.202) port 80 (#0)
+> GET /get HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.1.2
+> Accept: */*
+>
+* Recv failure: Connection reset by peer
+* Closing connection 0
+curl: (56) Recv failure: Connection reset by peer
+```
+
+Curl the example app through Envoy proxy once again, now sending HAProxy PROXY protocol header at the beginning of the connection with --haproxy-protocol flag:
+
+```shell
+curl --verbose --haproxy-protocol --header "Host: www.example.com" http://$GATEWAY_HOST/get
+```
+
+You should now expect 200 response status and also see that source IP was preserved in the X-Forwarded-For header.
+
+```shell
+* Trying 172.18.255.202:80...
+* Connected to 172.18.255.202 (172.18.255.202) port 80 (#0)
+> GET /get HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.1.2
+> Accept: */*
+>
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< date: Mon, 04 Dec 2023 21:11:43 GMT
+< content-length: 510
+< x-envoy-upstream-service-time: 0
+< server: envoy
+<
+{
+ "path": "/get",
+ "host": "www.example.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/8.1.2"
+ ],
+ "X-Envoy-Expected-Rq-Timeout-Ms": [
+ "15000"
+ ],
+ "X-Envoy-Internal": [
+ "true"
+ ],
+ "X-Forwarded-For": [
+ "192.168.255.6"
+ ],
+ "X-Forwarded-Proto": [
+ "http"
+ ],
+ "X-Request-Id": [
+ "290e4b61-44b7-4e5c-a39c-0ec76784e897"
+ ]
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-58d58f745-2zwvn"
+* Connection #0 to host 172.18.255.202 left intact
+}
+```
+
+### Configure Client IP Detection
+
+This example configures the number of additional ingress proxy hops from the right side of XFF HTTP headers to trust when determining the origin client's IP address and determines whether or not `x-forwarded-proto` headers will be trusted. Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for for details.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Verify that ClientTrafficPolicy is Accepted:
+
+```shell
+kubectl get clienttrafficpolicies.gateway.envoyproxy.io -n default
+```
+
+You should see the policy marked as accepted like this:
+
+```shell
+NAME STATUS AGE
+http-client-ip-detection Accepted 5s
+```
+
+Open port-forward to the admin interface port:
+
+```shell
+kubectl port-forward deploy/${ENVOY_DEPLOYMENT} -n envoy-gateway-system 19000:19000
+```
+
+Curl the admin interface port to fetch the configured value for `xff_num_trusted_hops`:
+
+```shell
+curl -s 'http://localhost:19000/config_dump?resource=dynamic_listeners' \
+ | jq -r '.configs[0].active_state.listener.default_filter_chain.filters[0].typed_config
+ | with_entries(select(.key | match("xff|remote_address|original_ip")))'
+```
+
+You should expect to see the following:
+
+```json
+{
+ "use_remote_address": true,
+ "xff_num_trusted_hops": 2
+}
+```
+
+Curl the example app through Envoy proxy:
+
+```shell
+curl -v http://$GATEWAY_HOST/get \
+ -H "Host: www.example.com" \
+ -H "X-Forwarded-Proto: https" \
+ -H "X-Forwarded-For: 1.1.1.1,2.2.2.2"
+```
+
+You should expect 200 response status, see that `X-Forwarded-Proto` was preserved and `X-Envoy-External-Address` was set to the leftmost address in the `X-Forwarded-For` header:
+
+```shell
+* Trying [::1]:8888...
+* Connected to localhost (::1) port 8888
+> GET /get HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.4.0
+> Accept: */*
+> X-Forwarded-Proto: https
+> X-Forwarded-For: 1.1.1.1,2.2.2.2
+>
+Handling connection for 8888
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< date: Tue, 30 Jan 2024 15:19:22 GMT
+< content-length: 535
+< x-envoy-upstream-service-time: 0
+< server: envoy
+<
+{
+ "path": "/get",
+ "host": "www.example.com",
+ "method": "GET",
+ "proto": "HTTP/1.1",
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "User-Agent": [
+ "curl/8.4.0"
+ ],
+ "X-Envoy-Expected-Rq-Timeout-Ms": [
+ "15000"
+ ],
+ "X-Envoy-External-Address": [
+ "1.1.1.1"
+ ],
+ "X-Forwarded-For": [
+ "1.1.1.1,2.2.2.2,10.244.0.9"
+ ],
+ "X-Forwarded-Proto": [
+ "https"
+ ],
+ "X-Request-Id": [
+ "53ccfad7-1899-40fa-9322-ddb833aa1ac3"
+ ]
+ },
+ "namespace": "default",
+ "ingress": "",
+ "service": "",
+ "pod": "backend-58d58f745-8psnc"
+* Connection #0 to host localhost left intact
+}
+```
+
+### Enable HTTP Request Received Timeout
+
+This feature allows you to limit the time taken by the Envoy Proxy fleet to receive the entire request from the client, which is useful in preventing certain clients from consuming too much memory in Envoy
+This example configures the HTTP request timeout for the client, please check out the details [here](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#stream-timeouts).
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Curl the example app through Envoy proxy:
+
+```shell
+curl -v http://$GATEWAY_HOST/get \
+ -H "Host: www.example.com" \
+ -H "Content-Length: 10000"
+```
+
+You should expect `428` response status after 2s:
+
+```shell
+curl -v http://$GATEWAY_HOST/get \
+ -H "Host: www.example.com" \
+ -H "Content-Length: 10000"
+* Trying 172.18.255.200:80...
+* Connected to 172.18.255.200 (172.18.255.200) port 80
+> GET /get HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.4.0
+> Accept: */*
+> Content-Length: 10000
+>
+< HTTP/1.1 408 Request Timeout
+< content-length: 15
+< content-type: text/plain
+< date: Tue, 27 Feb 2024 07:38:27 GMT
+< connection: close
+<
+* Closing connection
+request timeout
+```
+
+### Configure Client HTTP Idle Timeout
+
+The idle timeout is defined as the period in which there are no active requests. When the idle timeout is reached the connection will be closed.
+For more details see [here](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout:~:text=...%7D%0A%7D-,idle_timeout,-(Duration)%20The).
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Curl the example app through Envoy proxy:
+
+```shell
+openssl s_client -crlf -connect $GATEWAY_HOST:443
+```
+
+You should expect the connection to be closed after 5s.
+
+You can also check the number of connections closed due to idle timeout by using the following query:
+
+```shell
+envoy_http_downstream_cx_idle_timeout{envoy_http_conn_manager_prefix=""}
+```
+
+The number of connections closed due to idle timeout should be increased by 1.
+
+
+### Configure Downstream Per Connection Buffer Limit
+
+This feature allows you to set a soft limit on size of the listener’s new connection read and write buffers.
+The size is configured using the `resource.Quantity` format, see examples [here](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-memory).
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+[ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy
+[BackendTrafficPolicy]: ../../../api/extension_types#backendtrafficpolicy
diff --git a/site/content/en/v1.2/tasks/traffic/connection-limit.md b/site/content/en/v1.2/tasks/traffic/connection-limit.md
new file mode 100644
index 00000000000..9c0e9bbc1fc
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/connection-limit.md
@@ -0,0 +1,135 @@
+---
+title: "Connection Limit"
+---
+
+The connection limit features allows users to limit the number of concurrently active TCP connections on a [Gateway][] or a [Listener][].
+When the [connection limit][] is reached, new connections are closed immediately by Envoy proxy. It's possible to configure a delay for connection rejection.
+
+Users may want to limit the number of connections for several reasons:
+* Protect resources like CPU and Memory.
+* Ensure that different listeners can receive a fair share of global resources.
+* Protect from malicious activity like DoS attacks.
+
+Envoy Gateway introduces a new CRD called [Client Traffic Policy][] that allows the user to describe their desired connection limit settings.
+This instantiated resource can be linked to a [Gateway][].
+
+The Envoy [connection limit][] implementation is distributed: counters are not synchronized between different envoy proxies.
+
+When a [Client Traffic Policy][] is attached to a gateway, the connection limit will apply differently based on the
+[Listener][] protocol in use:
+- HTTP: all HTTP listeners in a [Gateway][] will share a common connection counter, and a limit defined by the policy.
+- HTTPS/TLS: each HTTPS/TLS listener will have a dedicated connection counter, and a limit defined by the policy.
+
+
+## Prerequisites
+
+### Install Envoy Gateway
+
+{{< boilerplate prerequisites >}}
+
+### Install the hey load testing tool
+
+* The `hey` CLI will be used to generate load and measure response times. Follow the installation instruction from the [Hey project] docs.
+
+## Test and customize connection limit settings
+
+This example we use `hey` to open 10 connections and execute 1 RPS per connection for 10 seconds.
+
+```shell
+hey -c 10 -q 1 -z 10s -host "www.example.com" http://${GATEWAY_HOST}/get
+```
+
+```console
+Summary:
+ Total: 10.0058 secs
+ Slowest: 0.0275 secs
+ Fastest: 0.0029 secs
+ Average: 0.0111 secs
+ Requests/sec: 9.9942
+
+[...]
+
+Status code distribution:
+ [200] 100 responses
+```
+
+There are no connection limits, and so all 100 requests succeed.
+
+Next, we apply a limit of 5 connections.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Execute the load simulation again.
+
+```shell
+hey -c 10 -q 1 -z 10s -host "www.example.com" http://${GATEWAY_HOST}/get
+```
+
+```console
+Summary:
+ Total: 11.0327 secs
+ Slowest: 0.0361 secs
+ Fastest: 0.0013 secs
+ Average: 0.0088 secs
+ Requests/sec: 9.0640
+
+[...]
+
+Status code distribution:
+ [200] 50 responses
+
+Error distribution:
+ [50] Get "http://localhost:8888/get": EOF
+```
+
+With the new connection limit, only 5 of 10 connections are established, and so only 50 requests succeed.
+
+
+[Client Traffic Policy]: ../../../api/extension_types#clienttrafficpolicy
+[Hey project]: https://github.com/rakyll/hey
+[connection limit]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/connection_limit_filter
+[listener]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Listener
+[gateway]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.Gateway
diff --git a/site/content/en/v1.2/tasks/traffic/direct-response.md b/site/content/en/v1.2/tasks/traffic/direct-response.md
new file mode 100644
index 00000000000..dfaa6755d4d
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/direct-response.md
@@ -0,0 +1,203 @@
+---
+title: "Direct Response"
+---
+
+Direct responses are valuable in cases where you want the gateway itself
+to handle certain requests without forwarding them to backend services.
+This task shows you how to configure them.
+
+## Installation
+
+Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+## Testing Direct Response
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/inline
+```
+
+```console
+* Trying 127.0.0.1:80...
+* Connected to 127.0.0.1 (127.0.0.1) port 80
+> GET /inline HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.4.0
+> Accept: */*
+>
+< HTTP/1.1 503 Service Unavailable
+< content-type: text/plain
+< content-length: 32
+< date: Sat, 02 Nov 2024 00:35:48 GMT
+<
+* Connection #0 to host 127.0.0.1 left intact
+Oops! Your request is not found.
+```
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/value-ref
+```
+
+```console
+* Trying 127.0.0.1:80...
+* Connected to 127.0.0.1 (127.0.0.1) port 80
+> GET /value-ref HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.4.0
+> Accept: */*
+>
+< HTTP/1.1 500 Internal Server Error
+< content-type: application/json
+< content-length: 34
+< date: Sat, 02 Nov 2024 00:35:55 GMT
+<
+* Connection #0 to host 127.0.0.1 left intact
+{"error": "Internal Server Error"}
+```
diff --git a/site/content/en/v1.2/tasks/traffic/failover.md b/site/content/en/v1.2/tasks/traffic/failover.md
new file mode 100644
index 00000000000..625d5e2afcd
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/failover.md
@@ -0,0 +1,566 @@
+---
+title: Failover
+---
+
+Active-passive failover in an API gateway setup is like having a backup plan in place to keep things
+running smoothly if something goes wrong. Here’s why it’s valuable:
+
+* Staying Online: When the main (or "active") backend has issues or goes offline,
+the fallback (or "passive") backend is ready to step in instantly.
+This helps keep your API accessible and your services running, so users don’t even notice any interruptions.
+
+* Automatic Switch Over: If a problem occurs, the system can automatically switch traffic over to the fallback backend.
+This avoids needing someone to jump in and fix things manually, which could take time and might even lead to mistakes.
+
+* Lower Costs: In an active-passive setup, the fallback backend doesn’t need to work all the time—it’s just on standby.
+This can save on costs (like cloud egress costs) compared to setups where both backend are running at full capacity.
+
+* Peace of Mind with Redundancy: Although the fallback backend isn’t handling traffic daily, it's there as a safety net.
+If something happens with the primary backend, the backup can take over immediately, ensuring your service doesn’t skip a beat.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## Test
+
+* We'll first create two services & deployments, called `active` and `passive`, representing an `active` and `passive` backend application.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+* Follow the instructions [here](./../../tasks/traffic/backend/#enable-backend) to enable the Backend API
+
+* Create two Backend resources that are used to represent the `active` backend and `passive` backend.
+Note, we've set `fallback: true` for the `passive` backend to indicate its a passive backend
+
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+* Lets create an HTTPRoute that can route to both these backends
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+* Lets configure a `BackendTrafficPolicy` with a passive health check setting to detect an transient errors.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+
+* Lets send 10 requests. You should see that they all go to the `active` backend.
+
+```shell
+for i in {1..10; do curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/test 2>/dev/null | jq .pod; done
+```
+
+```console
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+"active-5bb896774f-lz8s9"
+```
+
+* Lets simulate a failure in the `active` backend by changing the server listening port to `5000`
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+* Lets send 10 requests again. You should see them all being sent to the `passive` backend
+
+```shell
+for i in {1..10; do curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/test 2>/dev/null | jq .pod; done
+```
+
+```console
+parse error: Invalid numeric literal at line 1, column 9
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+"passive-7ddbf945c9-wkc4f"
+```
+
+The first error can be avoided by configuring [retries](./../../tasks/traffic/retry.md).
diff --git a/site/content/en/v1.2/tasks/traffic/fault-injection.md b/site/content/en/v1.2/tasks/traffic/fault-injection.md
new file mode 100644
index 00000000000..82068c4cf55
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/fault-injection.md
@@ -0,0 +1,382 @@
+---
+title: "Fault Injection"
+---
+
+[Envoy fault injection] can be used to inject delays and abort requests to mimic failure scenarios such as service failures and overloads.
+
+Envoy Gateway supports the following fault scenarios:
+- **delay fault**: inject a custom fixed delay into the request with a certain probability to simulate delay failures.
+- **abort fault**: inject a custom response code into the response with a certain probability to simulate abort failures.
+
+Envoy Gateway introduces a new CRD called [BackendTrafficPolicy][] that allows the user to describe their desired fault scenarios.
+This instantiated resource can be linked to a [Gateway][], [HTTPRoute][] or [GRPCRoute][] resource.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+For GRPC - follow the steps from the [GRPC Routing](../grpc-routing) example.
+
+### Install the hey load testing tool
+
+* The `hey` CLI will be used to generate load and measure response times. Follow the installation instruction from the [Hey project] docs.
+
+## Configuration
+
+Allow requests with a valid faultInjection by creating an [BackendTrafficPolicy][BackendTrafficPolicy] and attaching it to the example HTTPRoute or GRPCRoute.
+
+### HTTPRoute
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+Two HTTPRoute resources were created, one for `/foo` and another for `/bar`. `fault-injection-abort` BackendTrafficPolicy has been created and targeted HTTPRoute foo to abort requests for `/foo`. `fault-injection-delay` BackendTrafficPolicy has been created and targeted HTTPRoute foo to delay `2s` requests for `/bar`.
+
+Verify the HTTPRoute configuration and status:
+
+```shell
+kubectl get httproute/foo -o yaml
+kubectl get httproute/bar -o yaml
+```
+
+Verify the BackendTrafficPolicy configuration:
+
+```shell
+kubectl get backendtrafficpolicy/fault-injection-50-percent-abort -o yaml
+kubectl get backendtrafficpolicy/fault-injection-delay -o yaml
+```
+
+### GRPCRoute
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+A BackendTrafficPolicy has been created and targeted GRPCRoute yages to abort requests for `yages` service..
+
+Verify the GRPCRoute configuration and status:
+
+```shell
+kubectl get grpcroute/yages -o yaml
+```
+
+Verify the SecurityPolicy configuration:
+
+```shell
+kubectl get backendtrafficpolicy/fault-injection-abort -o yaml
+```
+
+## Testing
+
+Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
+Quickstart instructions to set the variable.
+
+```shell
+echo $GATEWAY_HOST
+```
+
+### HTTPRoute
+
+Verify that requests to `foo` route are aborted.
+
+```shell
+hey -n 1000 -c 100 -host "www.example.com" http://${GATEWAY_HOST}/foo
+```
+
+```console
+Status code distribution:
+ [200] 501 responses
+ [501] 499 responses
+```
+
+Verify that requests to `bar` route are delayed.
+
+```shell
+hey -n 1000 -c 100 -host "www.example.com" http://${GATEWAY_HOST}/bar
+```
+
+```console
+Summary:
+ Total: 20.1493 secs
+ Slowest: 2.1020 secs
+ Fastest: 1.9940 secs
+ Average: 2.0123 secs
+ Requests/sec: 49.6295
+
+ Total data: 557000 bytes
+ Size/request: 557 bytes
+
+Response time histogram:
+ 1.994 [1] |
+ 2.005 [475] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 2.016 [419] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
+ 2.026 [5] |
+ 2.037 [0] |
+ 2.048 [0] |
+ 2.059 [30] |■■■
+ 2.070 [0] |
+ 2.080 [0] |
+ 2.091 [11] |■
+ 2.102 [59] |■■■■■
+```
+
+### GRPCRoute
+
+Verify that requests to `yages`service are aborted.
+
+```shell
+grpcurl -plaintext -authority=grpc-example.com ${GATEWAY_HOST}:80 yages.Echo/Ping
+```
+
+You should see the below response
+
+```shell
+Error invoking method "yages.Echo/Ping": rpc error: code = Unavailable desc = failed to query for service descriptor "yages.Echo": fault filter abort
+```
+
+## Clean-Up
+
+Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest.
+
+Delete the BackendTrafficPolicy:
+
+```shell
+kubectl delete BackendTrafficPolicy/fault-injection-abort
+```
+
+[Envoy fault injection]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/fault_filter.html
+[BackendTrafficPolicy]: ../../../api/extension_types#backendtrafficpolicy
+[Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway/
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/
+[GRPCRoute]: https://gateway-api.sigs.k8s.io/api-types/grpcroute/
+[Hey project]: https://github.com/rakyll/hey
diff --git a/site/content/en/v1.2/tasks/traffic/gateway-address.md b/site/content/en/v1.2/tasks/traffic/gateway-address.md
new file mode 100644
index 00000000000..f49d7f99e01
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/gateway-address.md
@@ -0,0 +1,68 @@
+---
+title: "Gateway Address"
+---
+
+The Gateway API provides an optional [Addresses][] field through which Envoy Gateway can set addresses for Envoy Proxy Service.
+Depending on the Service Type, the addresses of gateway can be used as:
+
+- [External IPs](#external-ips)
+- [Cluster IP](#cluster-ip)
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+## External IPs
+
+Using the addresses in `Gateway.Spec.Addresses` as the [External IPs][] of Envoy Proxy Service,
+this will __require__ the address to be of type `IPAddress` and the [ServiceType][] to be of `LoadBalancer` or `NodePort`.
+
+The Envoy Gateway deploys Envoy Proxy Service as `LoadBalancer` by default,
+so you can set the address of the Gateway directly (the address settings here are for reference only):
+
+```shell
+kubectl patch gateway eg --type=json --patch '
+- op: add
+ path: /spec/addresses
+ value:
+ - type: IPAddress
+ value: 1.2.3.4
+'
+```
+
+Verify the Gateway status:
+
+```shell
+kubectl get gateway
+```
+
+```console
+NAME CLASS ADDRESS PROGRAMMED AGE
+eg eg 1.2.3.4 True 14m
+```
+
+Verify the Envoy Proxy Service status:
+
+```shell
+kubectl get service -n envoy-gateway-system
+```
+
+```console
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+envoy-default-eg-64656661 LoadBalancer 10.96.236.219 1.2.3.4 80:31017/TCP 15m
+envoy-gateway ClusterIP 10.96.192.76 18000/TCP 15m
+envoy-gateway-metrics-service ClusterIP 10.96.124.73 8443/TCP 15m
+```
+
+__Note:__ If the `Gateway.Spec.Addresses` is explicitly set, it will be the only addresses that populates the Gateway status.
+
+## Cluster IP
+
+Using the addresses in `Gateway.Spec.Addresses` as the [Cluster IP][] of Envoy Proxy Service,
+this will __require__ the address to be of type `IPAddress` and the [ServiceType][] to be of `ClusterIP`.
+
+
+[Addresses]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayAddress
+[External IPs]: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips
+[Cluster IP]: https://kubernetes.io/docs/concepts/services-networking/service/#type-clusterip
+[ServiceType]: ../../../api/extension_types#servicetype
diff --git a/site/content/en/v1.2/tasks/traffic/gatewayapi-support.md b/site/content/en/v1.2/tasks/traffic/gatewayapi-support.md
new file mode 100644
index 00000000000..779cce6fb12
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/gatewayapi-support.md
@@ -0,0 +1,120 @@
+---
+title: "Gateway API Support"
+---
+
+As mentioned in the [system design][] document, Envoy Gateway's managed data plane is configured dynamically through
+Kubernetes resources, primarily [Gateway API][] objects. Envoy Gateway supports configuration using the following Gateway API resources.
+
+## GatewayClass
+
+A [GatewayClass][] represents a "class" of gateways, i.e. which Gateways should be managed by Envoy Gateway.
+Envoy Gateway supports managing __a single__ GatewayClass resource that matches its configured `controllerName` and
+follows Gateway API guidelines for [resolving conflicts][] when multiple GatewayClasses exist with a matching
+`controllerName`.
+
+__Note:__ If specifying GatewayClass [parameters reference][], it must refer to an [EnvoyProxy][] resource.
+
+## Gateway
+
+When a [Gateway][] resource is created that references the managed GatewayClass, Envoy Gateway will create and manage a
+new Envoy Proxy deployment. Gateway API resources that reference this Gateway will configure this managed Envoy Proxy
+deployment.
+
+## HTTPRoute
+
+A [HTTPRoute][] configures routing of HTTP traffic through one or more Gateways. The following HTTPRoute filters are
+supported by Envoy Gateway:
+
+- `requestHeaderModifier`: [RequestHeaderModifiers][http-filter]
+ can be used to modify or add request headers before the request is proxied to its destination.
+- `responseHeaderModifier`: [ResponseHeaderModifiers][http-filter]
+ can be used to modify or add response headers before the response is sent back to the client.
+- `requestMirror`: [RequestMirrors][http-filter]
+ configure destinations where the requests should also be mirrored to. Responses to mirrored requests will be ignored.
+- `requestRedirect`: [RequestRedirects][http-filter]
+ configure policied for how requests that match the HTTPRoute should be modified and then redirected.
+- `urlRewrite`: [UrlRewrites][http-filter]
+ allow for modification of the request's hostname and path before it is proxied to its destination.
+- `extensionRef`: [ExtensionRefs][] are used by Envoy Gateway to implement extended filters. Currently, Envoy Gateway
+ supports rate limiting and request authentication filters. For more information about these filters, refer to the
+ [rate limiting][] and [request authentication][] documentation.
+
+__Notes:__
+- The only [BackendRef][] kind supported by Envoy Gateway is a [Service][]. Routing traffic to other destinations such
+ as arbitrary URLs is not possible.
+- Only `requestHeaderModifier` and `responseHeaderModifier` filters are currently supported within [HTTPBackendRef][].
+
+## TCPRoute
+
+A [TCPRoute][] configures routing of raw TCP traffic through one or more Gateways. Traffic can be forwarded to the
+desired BackendRefs based on a TCP port number.
+
+__Note:__ A TCPRoute only supports proxying in non-transparent mode, i.e. the backend will see the source IP and port of
+the Envoy Proxy instance instead of the client.
+
+## UDPRoute
+
+A [UDPRoute][] configures routing of raw UDP traffic through one or more Gateways. Traffic can be forwarded to the
+desired BackendRefs based on a UDP port number.
+
+__Note:__ Similar to TCPRoutes, UDPRoutes only support proxying in non-transparent mode i.e. the backend will see the
+source IP and port of the Envoy Proxy instance instead of the client.
+
+## GRPCRoute
+
+A [GRPCRoute][] configures routing of [gRPC][] requests through one or more Gateways. They offer request matching by
+hostname, gRPC service, gRPC method, or HTTP/2 Header. Envoy Gateway supports the following filters on GRPCRoutes to
+provide additional traffic processing:
+
+- `requestHeaderModifier`: [RequestHeaderModifiers][grpc-filter]
+ can be used to modify or add request headers before the request is proxied to its destination.
+- `responseHeaderModifier`: [ResponseHeaderModifiers][grpc-filter]
+ can be used to modify or add response headers before the response is sent back to the client.
+- `requestMirror`: [RequestMirrors][grpc-filter]
+ configure destinations where the requests should also be mirrored to. Responses to mirrored requests will be ignored.
+
+__Notes:__
+- The only [BackendRef][grpc-filter] kind supported by Envoy Gateway is a [Service][]. Routing traffic to other
+ destinations such as arbitrary URLs is not currently possible.
+- Only `requestHeaderModifier` and `responseHeaderModifier` filters are currently supported within [GRPCBackendRef][].
+
+## TLSRoute
+
+A [TLSRoute][] configures routing of TCP traffic through one or more Gateways. However, unlike TCPRoutes, TLSRoutes
+can match against TLS-specific metadata.
+
+## ReferenceGrant
+
+A [ReferenceGrant][] is used to allow a resource to reference another resource in a different namespace. Normally an
+HTTPRoute created in namespace `foo` is not allowed to reference a Service in namespace `bar`. A ReferenceGrant permits
+these types of cross-namespace references. Envoy Gateway supports the following ReferenceGrant use-cases:
+
+- Allowing an HTTPRoute, GRPCRoute, TLSRoute, UDPRoute, or TCPRoute to reference a Service in a different namespace.
+- Allowing an HTTPRoute's `requestMirror` filter to include a BackendRef that references a Service in a different
+ namespace.
+- Allowing a Gateway's [SecretObjectReference][] to reference a secret in a different namespace.
+
+[system design]: ../../../contributions/design/system-design
+[Gateway API]: https://gateway-api.sigs.k8s.io/
+[GatewayClass]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass
+[parameters reference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ParametersReference
+[Gateway]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Gateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute
+[Service]: https://kubernetes.io/docs/concepts/services-networking/service/
+[BackendRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.BackendRef
+[HTTPBackendRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPBackendRef
+[TCPRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute
+[UDPRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.UDPRoute
+[GRPCRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute
+[GRPCBackendRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GRPCBackendRef
+[gRPC]: https://grpc.io/
+[TLSRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute
+[ReferenceGrant]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.ReferenceGrant
+[SecretObjectReference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.SecretObjectReference
+[rate limiting]: ../../../contributions/design/rate-limit
+[request authentication]: ../security/jwt-authentication
+[EnvoyProxy]: ../../../api/extension_types#envoyproxy
+[resolving conflicts]: https://gateway-api.sigs.k8s.io/concepts/guidelines/?h=conflict#conflicts
+[ExtensionRefs]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilterType
+[grpc-filter]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRouteFilter
+[http-filter]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter
diff --git a/site/content/en/v1.2/tasks/traffic/global-rate-limit.md b/site/content/en/v1.2/tasks/traffic/global-rate-limit.md
new file mode 100644
index 00000000000..47eac33bc3e
--- /dev/null
+++ b/site/content/en/v1.2/tasks/traffic/global-rate-limit.md
@@ -0,0 +1,1339 @@
+---
+title: "Global Rate Limit"
+---
+
+Rate limit is a feature that allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow.
+
+Here are some reasons why you may want to implement Rate limits
+
+* To prevent malicious activity such as DDoS attacks.
+* To prevent applications and its resources (such as a database) from getting overloaded.
+* To create API limits based on user entitlements.
+
+Envoy Gateway supports two types of rate limiting: [Global rate limiting][] and [Local rate limiting][].
+
+[Global rate limiting][] applies a shared rate limit to the traffic flowing through all the instances of Envoy proxies where it is configured.
+i.e. if the data plane has 2 replicas of Envoy running, and the rate limit is 10 requests/second, this limit is shared and will be hit
+if 5 requests pass through the first replica and 5 requests pass through the second replica within the same second.
+
+Envoy Gateway introduces a new CRD called [BackendTrafficPolicy][] that allows the user to describe their rate limit intent. This instantiated resource
+can be linked to a [Gateway][], [HTTPRoute][] or [GRPCRoute][] resource.
+
+**Note:** Limit is applied per route. Even if a [BackendTrafficPolicy][] targets a gateway, each route in that gateway
+still has a separate rate limit bucket. For example, if a gateway has 2 routes, and the limit is 100r/s, then each route
+has its own 100r/s rate limit bucket.
+
+## Prerequisites
+
+### Install Envoy Gateway
+
+{{< boilerplate prerequisites >}}
+
+### Install Redis
+
+* The global rate limit feature is based on [Envoy Ratelimit][] which requires a Redis instance as its caching layer.
+Lets install a Redis deployment in the `redis-system` namespce.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+### Enable Global Rate limit in Envoy Gateway
+
+* The default installation of Envoy Gateway installs a default [EnvoyGateway][] configuration and attaches it
+using a `ConfigMap`. In the next step, we will update this resource to enable rate limit in Envoy Gateway
+as well as configure the URL for the Redis instance used for Global rate limiting.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+{{< boilerplate rollout-envoy-gateway >}}
+
+## Rate Limit Specific User
+
+Here is an example of a rate limit implemented by the application developer to limit a specific user by matching on a custom `x-user-id` header
+with a value set to `one`.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+### HTTPRoute
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway.
+
+```shell
+kubectl get httproute/http-ratelimit -o yaml
+```
+
+Get the Gateway's address:
+
+```shell
+export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
+```
+
+Let's query `ratelimit.example/get` 4 times. We should receive a `200` response from the example Gateway for the first 3 requests
+and then receive a `429` status code for the 4th request since the limit is set at 3 requests/Hour for the request which contains the header `x-user-id`
+and value `one`.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: one" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 429 Too Many Requests
+x-envoy-ratelimited: true
+date: Wed, 08 Feb 2023 02:33:34 GMT
+server: envoy
+transfer-encoding: chunked
+
+```
+
+You should be able to send requests with the `x-user-id` header and a different value and receive successful responses from the server.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: two" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:34:36 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:34:37 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:34:38 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:34:39 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+```
+
+## Rate Limit Distinct Users Except Admin
+
+Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differentiated based on the
+value in the `x-user-id` header. Here, user `one` (recognised from the traffic flow using the header `x-user-id` and value `one`) will be rate limited at 3 requests/hour
+and so will user `two` (recognised from the traffic flow using the header `x-user-id` and value `two`). But if `x-user-id` is `admin`, it will not be rate limited even beyond 3 requests/hour.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+### HTTPRoute
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Lets run the same command again with the header `x-user-id` and value `one` set in the request. We should the first 3 requests succeeding and
+the 4th request being rate limited.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: one" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 429 Too Many Requests
+x-envoy-ratelimited: true
+date: Wed, 08 Feb 2023 02:33:34 GMT
+server: envoy
+transfer-encoding: chunked
+
+```
+
+You should see the same behavior when the value for header `x-user-id` is set to `two` and 4 requests are sent.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: two" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 429 Too Many Requests
+x-envoy-ratelimited: true
+date: Wed, 08 Feb 2023 02:33:34 GMT
+server: envoy
+transfer-encoding: chunked
+
+```
+
+But when the value for header `x-user-id` is set to `admin` and 4 requests are sent, all 4 of them should respond with 200 OK.
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: admin" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+```
+
+## Rate Limit All Requests
+
+This example shows you how to rate limit all requests matching the HTTPRoute rule at 3 requests/Hour by leaving the `clientSelectors` field unset.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+### HTTPRoute
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+```shell
+for i in {1..4}; do curl -I --header "Host: ratelimit.example" http://${GATEWAY_HOST}/get ; sleep 1; done
+```
+
+```console
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:31 GMT
+content-length: 460
+x-envoy-upstream-service-time: 4
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:32 GMT
+content-length: 460
+x-envoy-upstream-service-time: 2
+server: envoy
+
+HTTP/1.1 200 OK
+content-type: application/json
+x-content-type-options: nosniff
+date: Wed, 08 Feb 2023 02:33:33 GMT
+content-length: 460
+x-envoy-upstream-service-time: 0
+server: envoy
+
+HTTP/1.1 429 Too Many Requests
+x-envoy-ratelimited: true
+date: Wed, 08 Feb 2023 02:33:34 GMT
+server: envoy
+transfer-encoding: chunked
+
+```
+
+## Rate Limit Client IP Addresses
+
+Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differentiated based on their
+ IP address (also reflected in the `X-Forwarded-For` header).
+
+Note: EG supports two kinds of rate limit for the IP address: Exact and Distinct.
+* Exact means that all IP addresses within the specified Source IP CIDR share the same rate limit bucket.
+* Distinct means that each IP address within the specified Source IP CIDR has its own rate limit bucket.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <